I've this data
x ← ((1 'data1') (0 'data2') (0 'data3') (1 'data4') )
x
┌─────────┬─────────┬─────────┬─────────┐
│┌─┬─────┐│┌─┬─────┐│┌─┬─────┐│┌─┬─────┐│
││1│data1│││0│data2│││0│data3│││1│data4││
│└─┴─────┘│└─┴─────┘│└─┴─────┘│└─┴─────┘│
└─────────┴─────────┴─────────┴─────────┘
I would like to filter the array like this
┌─────────┬─────────┐
│┌─┬─────┐│┌─┬─────┐│
││1│data1│││1│data4││
│└─┴─────┘│└─┴─────┘│
└─────────┴─────────┘
How can I achieve this?
I've tried this but it didn't work, it takes in account the first element only.
((⊃y)[1])/y←x
┌─────────┬─────────┬─────────┬─────────┐
│┌─┬─────┐│┌─┬─────┐│┌─┬─────┐│┌─┬─────┐│
││1│data1│││0│data2│││0│data3│││1│data4││
│└─┴─────┘│└─┴─────┘│└─┴─────┘│└─┴─────┘│
└─────────┴─────────┴─────────┴─────────┘
Good news is that you got it almost right. Not bad for your first day of APL!
This minimal change to your code will do the trick:
((⊃¨y)=1)/y←x
┌─────────┬─────────┐
│┌─┬─────┐│┌─┬─────┐│
││1│data1│││1│data4││
│└─┴─────┘│└─┴─────┘│
└─────────┴─────────┘
However, there's no need to make a copy of x
into y
, since APL is normally pass-by-value. Furthermore, =
is commutative, so we can get rid of the inner parenthesis:
(1=⊃¨x)/x
┌─────────┬─────────┐
│┌─┬─────┐│┌─┬─────┐│
││1│data1│││1│data4││
│└─┴─────┘│└─┴─────┘│
└─────────┴─────────┘
You can then assign this to y
:
y← (1=⊃¨x)/x
y
┌─────────┬─────────┐
│┌─┬─────┐│┌─┬─────┐│
││1│data1│││1│data4││
│└─┴─────┘│└─┴─────┘│
└─────────┴─────────┘
In fact, we can get rid of the outer parenthesis too, by explicitly commuting /
:
x/⍨1=⊃¨x
┌─────────┬─────────┐
│┌─┬─────┐│┌─┬─────┐│
││1│data1│││1│data4││
│└─┴─────┘│└─┴─────┘│
└─────────┴─────────┘
Alternatively, we can make y
a copy of x
and then filter y
in-place:
y/⍨←1=⊃¨y←x
y
┌─────────┬─────────┐
│┌─┬─────┐│┌─┬─────┐│
││1│data1│││1│data4││
│└─┴─────┘│└─┴─────┘│
└─────────┴─────────┘