see also http://www.jsoftware.com/help/phrases/merge_amend.htm
R.E. Boss > -----Oorspronkelijk bericht----- > Van: [email protected] > [mailto:[email protected]] Namens Simon Barker > Verzonden: maandag 28 januari 2013 17:49 > Aan: [email protected] > Onderwerp: Re: [Jprogramming] Conditional by filtering then merging an array > > (/:/:m){c0,c1 > > Based on an old APL idiom. > > -----Original Message----- > From: [email protected] > [mailto:[email protected]] On Behalf Of Zsbán Ambrus > Sent: 28 January 2013 16:37 > To: Programming forum > Subject: [Jprogramming] Conditional by filtering then merging an array > > 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 > > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
