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

Reply via email to