This question is about evaulating a conditional expression on each
element of a list.

Let's take a simple working example.  Let's say we have this input,

   ]a =: 10+i.10
10 11 12 13 14 15 16 17 18 19

and we want to invoke one of two different operations on its elements
according to this mask:

   ]m =: 1 p: a
0 1 0 1 0 0 0 1 0 1

We can of course do the operations individually, like this:

   m (-@])`(*:@])@.["0 a
_10 121 _12 169 _14 _15 _16 289 _18 361

Or we can compute both operations on the whole list then merge them like this:

   ]b =: m} (-a) ,: *:a
_10 121 _12 169 _14 _15 _16 289 _18 361

Octave (at least a recent enough version) does support this latter
method as well:

octave> a = 10:19,
a =
   10   11   12   13   14   15   16   17   18   19
octave> m = isprime(a),
m =
   0   1   0   1   0   0   0   1   0   1
octave> b = ifelse(m, a.^2, -a),
b =
   -10   121   -12   169   -14   -15   -16   289   -18   361

But it turns out the octavers have a different idiom for conditional
expressions, which works by breaking the list to two parts according
to the mask, invoke a list function on each part, then merge the two
lists.

octave> c1 = a(m).^2, c0 = -a(~m), c = []; c(m) = c1; c(~m) = c0,
c1 =
   121   169   289   361
c0 =
  -10  -12  -14  -15  -16  -18
c =
   -10   121   -12   169   -14   -15   -16   289   -18   361

Now breaking the list to two parts and running a list function on each
part is easy enough in J:

   ]c0 =: -(-.m)#a
_10 _12 _14 _15 _16 _18
   ]c1 =: *:m#a
121 169 289 361

But how do you merge the two resulting lists?  There are some ugly
ways, such as these

   ]c =: (I.-.m) C.^:_1 c1,c0
_10 121 _12 169 _14 _15 _16 289 _18 361
   (m#^:_1 c1) + ((-.m)#^:_1 c0) NB. works only for numeric lists
_10 121 _12 169 _14 _15 _16 289 _18 361
   m} ((-.m)#^:_1 c0) ,: (m#^:_1 c1)
_10 121 _12 169 _14 _15 _16 289 _18 361
   c0 (I.-.m)} m#^:_1 c1
_10 121 _12 169 _14 _15 _16 289 _18 361

but is there a nicer way to merge two lists according to a mask like
this?  The mask tells which of the two lists each element of the
result comes from but with the inputs containing only as many elements
as necessary?

Ambrus
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to