Search code examples
searchindexingj

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


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?


Solution

  • 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