Print values and it's associated index when working with vectors / matrix in J

Viewed 75

If I want to check how many values in a vector or matrix are less than a given value I can use +/ (a < 20). But what if I wanted to know both the specific value and it's index. Something like (2(value) 5(index)) as a table. I looked at i., i: (which give first and last position) and I. Does sorting first help?

1 Answers

A very common pattern in J is the creation of a mask from a filter and applying an action on and/or using the masked data in a hook or fork:

((actions) (filter)) (data)

For example:

NB. Random array
a =: ? 20 $ 10
6 3 9 0 3 3 0 6 2 9 2 4 6 8 7 4 6 1 7 1

NB. Filter and mask
f =: 5 < ]
m =: f a
1 0 1 0 0 0 0 1 0 1 0 0 1 1 1 0 1 0 1 0

NB. Values of a on m
m # a
6 9 6 9 6 8 7 6 7

NB. Indices of a on m
I. m
0 2 7 9 12 13 14 16 18

NB. Joint results
(I.m) ,: (m # a)
0 2 7 9 12 13 14 16 18
6 9 6 9  6  8  7  6  7

In other words, in this case you have m&# and f acting on a and I. acting on m. Notice that the final result can be derived from an action on m alone by commuting the arguments of copy #~:

(I. ,: (a #~ ]) m
0 2 7 9 12 13 14 16 18
6 9 6 9  6  8  7  6  7

and a can be pulled out from the action on m like so:

a ( (]I.) ,: (#~ ])) m

But since m itself is derived from an action (f) on a, we can write:

a ( (]I.) ,: (#~ ])) (f a)

which is a simple monadic hook y v (f y) → (v f) y.

Therefore:

action =: (]I.) ,: (#~ ])
filter =: 5 < ]
data =: a

(action filter) data
0 2 7 9 12 13 14 16 18
6 9 6 9  6  8  7  6  7
Related