Alexander Mikhailov wrote:
> "from the input array, take first element and do Foo to it.
> If the result is X, stop, otherwise get second element and
> do Foo to it. If the result is X, stop... etc. If the
> result of last element is still not X, return Y"
Roger Hui wrote:
> foo=: >:
> X=: 6
> }.^:(X ~: f...@{.)^:_ ] 3 1 4 1 5 9
> 5 9
>
Thomas Costigliola wrote:
> I think you can omit the second ^: for tiny performance gain:
> (}.~ X ~: f...@{.)^:_ ] 3 1 4 1 5 9
> 5 9
Very clean, very elegant. So, to finish the solution, and implement the
"else, return Y" clause (as well as the implied "return a single value"
constraint), we might write:
([: {.!.Y (}.~ X ~: f...@{.)^:_ ) 3 1 4 1 5 9
5
Making this a reusable verb:
foo =: >:
X =: 6
Y =: _999
justFooIt =: [: {.!.Y (}.~ X ~: f...@{.)^:_
justFooIt 3 1 4 1 5 9
5
Now let's confirm the "else, return Y" logic. We'll change X so it's not
found in the input, and re-fix the definition of justFooIt to pick up the
new value of X:
X =: 11
justFooIt =: [: {.!.Y (}.~ X ~: f...@{.)^:_
justFooIt 3 1 4 1 5 9
_999
That works fine, but it's a bit cumbersome to have to re-fix the definition
every time one of the parameters changes. Here's one way, that cleanly
separates the parameters:
Jfi =: conjunction def' [: {.!.n (] }.~ (~: u@:{.))^:_ '
11 foo Jfi Y 3 1 4 1 5 9
_999
6 foo Jfi Y 3 1 4 1 5 9
5
Here, Jfi is a conjunction, which, when given a verbal left argument (foo),
and a noun right argument (Y), derives a dyad whose left argument is X, and
right argument is the list to process.
We could make a further convenience, by defaulting the left argument of the
derived dyad to X (but providing the opportunity to override that decision):
Jfix =: 2 : ' (&$:) ( : (u Jfi n) ) '
fooSearch =: X foo Jfix Y NB. Function foo, default Y, target X
fooSearch 3 1 4 1 5 9 NB. Target (X=11) not found, use
default (Y=_999)
_999
6 fooSearch 3 1 4 1 5 9 NB. Change target, seek 6 instead of
X (11)
5
-----Original Message-----
From: [email protected] [mailto:[email protected]] On
Behalf Of Thomas Costigliola
Sent: Wednesday, June 09, 2010 11:12 AM
To: Chat forum
Subject: Re: [Jchat] on the J thought style again
On Wed, Jun 9, 2010 at 3:54 AM, Roger Hui <[email protected]> wrote:
> For example:
>
> foo=: >:
> X=: 6
> }.^:(X ~: f...@{.)^:_ ] 3 1 4 1 5 9
> 5 9
>
> I think you can omit the second ^: for tiny performance gain:
(}.~ X ~: f...@{.)^:_ ] 3 1 4 1 5 9
5 9
> A better solution, I think, is special code for (f i. 1:)
> for more general f, similar to the existing special code
> for (= i. 1:), (> i. 1:) etc.
>
> The following timing shows that something different
> is going on with (= i. 1:) vs. (x=y)i.1 :
>
> x=: ?1e6$100
> 6!:2 '1 (= i. 1:) x'
> 2.26286e_5
> 6!:2 '(1=x) i. 1'
> 0.00541857
>
>
>
> ----- Original Message -----
> From: Alexander Mikhailov <[email protected]>
> Date: Tuesday, June 8, 2010 23:22
> Subject: [Jchat] on the J thought style again
> To: [email protected]
>
> > I'm writing a function which goes roughly as the following:
> > "from the input array, take first element and do Foo to it. If
> > the result is X, stop, otherwise get second element and do Foo
> > to it. If the result is X, stop... etc. If the result of last
> > element is still not X, return Y"
> >
> > I started to write like this:
> >
> > Foo y
> >
> > and then I realize that I'm doing Foo to all elements of input
> > at once, even those which potentially won't be needed.
> >
> > So, trying to be optimal complicates things. A familiar observation.
> >
> > What would be an advice to J-ers? Clarity of idea - or, in
> > extreme cases, soundness of algorithm? Or, rather, how to find a
> > balance here?
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm