The solution I gave is a classic APL approach, which uses arithmetic to "replace" elements satisfying certain properties. Thus:
] x=: 10 ?...@$ 20 17 6 16 2 1 16 13 1 10 2 Replace odd elements by _1: x - (2|x) * 1+x _1 6 16 2 _1 16 _1 _1 10 2 Negate odd elements: x * _1 ^ 2|x _17 6 16 2 _1 16 _13 _1 10 2 Multiple odd elements by 1000: x * 1000 ^ 2|x 17000 6 16 2 1000 16 13000 1000 10 2 In general, if you have a boolean b having the same length as x, you can apply f to elements of x corresponding to 0s in b and g to elements of x corresponding to 1s, as follows: ((-.b)*f x) + b*g x Two reasons why you might want this approach: a. efficiency; b. bringing the computation into the nice world of expressions. Both reasons are somewhat undercut by the special code for c}x,y,:z implemented since J4.05: http://www.jsoftware.com/help/release/iamend.htm ----- Original Message ----- From: Zsbán Ambrus <[email protected]> Date: Monday, September 6, 2010 3:56 Subject: Re: [Jprogramming] replace/amend elements based on certain criteria ? To: Programming forum <[email protected]> > On Sun, Sep 5, 2010 at 7:05 PM, gary ng > <[email protected]> wrote: > > What would be the recommended way to do this , say replace every > > element that is odd to '_1' ? > > Has anyone shown the solution with the power conj yet? > This is > approperiate if the condition of what to replace depends on the value > of that one element only. > > ]a=: 12 ?...@$ 20 > 9 8 15 17 4 0 1 2 17 9 3 12 > _1:^:(2&|)"0 a > _1 8 _1 _1 4 0 _1 2 _1 _1 _1 12 > > This, of course, is more useful when you don't want to replace > with a > constant, but with a function of the previous value: > > _1&*^:(2&|)"0 a > _9 8 _15 _17 4 0 _1 2 _17 _9 _3 12 > > If you want to replace with a constant, then it might be easier to > extract the indices and use the amend conj: > > _1 (I.2|a)} a > _1 8 _1 _1 4 0 _1 2 _1 _1 _1 12 > > If you don't want to replace with a constant and which elements you > want to replace does not depend only on the values, then item amend > comes quite useful. Eg. suppose we want to replace all but > the first > occurrence of each number. Then we extract a mask for what > we want to > replace: > > ]m=: -.~:a > 0 0 0 0 0 0 0 0 1 1 0 0 > > and then we use item amend to replace: > > m} a,:_1 > 9 8 15 17 4 0 1 2 _1 _1 3 12 > m} a,:1e3*a > 9 8 15 17 4 0 1 2 17000 9000 3 12 > > There are, of course, lots of other possibilities. ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
