Reputation: 4007
Here is a simple replace for a rank-1 list using the I.
verb:
y=: _3 _2 _1 1 2 3
0 (I. y<0) } y
The result is
0 0 0 1 2 3
How do I do such a replacement for a rank-2 matrix?
For example,
y2 =: 2 3 $ _3 _2 _1 1 2 3
0 (I. y2<0) } y2
I got (J806)
|index error
| 0 (I.y2<2)}y2
The reason seems to be
(I. y2 < 0)
gives
0 1 2
0 0 0
which isn't taken well by }
.
Upvotes: 3
Views: 169
Reputation: 2463
The simplest answer for this problem is to use dyadic >.
(Larger of) ...
0 >. y2
0 0 0
1 2 3
If you want to use a more general conditional replacement criteria, then the following form may be useful:
(0 > y2)} y2 ,: 0
0 0 0
1 2 3
If you want it as a verb then you can use the gerund form (v1`v2)} y ↔ (v1 y)} (v2 y)
:
(0 > ])`(0 ,:~ ])} y2
0 0 0
1 2 3
If your question is more about scatter index replacement then that is possible too. You need to get the 2D indices of positions you want to replace, for example:
4 $. $. 0 > y2
0 0
0 1
0 2
Now box those indices and use dyadic }
:
0 (<"1 (4 $. $. 0 > y2)) } y2
0 0 0
1 2 3
Again you can turn this into a verb using a gerund left argument to dyadic }
(x (v0`v1`v2)} y ↔ (x v0 y) (x v1 y)} (x v2 y)
) like this:
0 [`([: (<"1) 4 $. [: $. 0 > ])`]} y2
0 0 0
1 2 3
Or
100 101 102 [`([: (<"1) 4 $. [: $. 0 > ])`]} y2
100 101 102
1 2 3
To tidy this up a bit you could define getIdx as separate verb...
getIdx=: 4 $. $.
0 [`([: <"1@getIdx 0 > ])`]} y2
0 0 0
1 2 3
Upvotes: 4
Reputation: 4302
This is not a good solution. My original approach was to change the rank of the test so that it looks at each row separately, but that does not work in the general case (see comments below).
[y2 =: 2 3 $ _3 _2 _1 1 2 3
_3 _2 _1
1 2 3
I. y2<0
0 1 2
0 0 0
0 (I. y2<0)"1 } y2 NB. Rank of 1 applies to each row of y2
0 0 0
1 2 3
Upvotes: 3