matrixvectorapl# APL - idiomatic way to filter, group, and sort from matrices

I am attempting to learn APL, but I am having a hard time writing code in an idiomatic way. Part of the problem, I believe, is that it is hard to find teaching material sufficiently broad and complete. For instance, consider the following problem: we have a matrix with n rows and 3 columns. Assume that all columns are of the same type. We want to obtain a vector of vectors of the elements on the second column, grouped by the value of the first column, and sorted by the value in the third column. So, for instance, for the input matrix

```
1 A 1
1 B 3
2 F 5
2 B 2
1 C 8
1 D 10
2 D 9
2 E 13
```

we would like the output to be

```
┌────┬────┐
│ABCD│BFDE│
└────┴────┘
```

I came up with:

`{1 ⌷[2]¨{(⍵[;1] {⍺ ⍵}⌸ ⍵[;2 3])[;2]} {↑(↓⍵)[⍋⍵[;3]]} ⍵}`

which works, but I am certain that there is a much easier, elegant, and idiomatic way to do this in APL. How would you do it?

Solution

```
input← (⍪1 1 2 2 1 1 2 2),(⍪'ABFBCDDE'),⍪1 3 5 2 8 10 9 13
{↓x[;1]⊢⌸2⌷[2]x←⍵[⍋⍵[;3];]}input
{x[;1]⊂⍤⊢⌸2⌷[2]x←⍵[⍋⍵[;3];]}input ⍝ fixed to reflect requested output format
```

Assume `⎕IO←1`

.

We want to obtain a vector of vectors of the elements on the second column, grouped by the value of the first column, and sorted by the value in the third column.

It is easier to achieve that by sort the input before regrouping using `⌸`

since it is good to know the order is preserved during regrouping.
While this behvavior is intuitive enough to be inferred from experimenting with this operator, the language reference clearly says.

The elements of R appear in the order in which they first appear in Y

`⊢⌸`

is equivalent and shorter form of `{⍵}⌸`

, of course.
(And `⊂⍤⊢⌸`

equivalent of `{⊂⍵}⌸`

)

Now, I have formed my solution independently, let's find what is the difference.

It seems you have observed the behavior of `⌸`

, then just be aware

that for the input data type of this problem,

`{↑(↓⍵)[⍋⍵[;3]]} ←→ {⍵[⍋⍵[;3];]}`

And it is rare for idiomatic APL code to nest dfns (aka anonymous function). So just open it:

```
{1 ⌷[2]¨{(⍵[;1] {⍺ ⍵}⌸ ⍵[;2 3])[;2]} ⍵[⍋⍵[;3];]}
```

If you don’t remove abstraction in APL code, you will lose the opportunity to seek further optimizations. The next function application can also be opened using local variable assignment,

```
{1 ⌷[2]¨(x[;1] {⍺ ⍵}⌸ x[;2 3])[;2]⊣x←⍵[⍋⍵[;3];]}
```

Now, since only the grouped data instead of index key is needed for the result, remove the redundancy altogether by keeping the data lean and efficient at first place:

```
{(x[;1]{⊂⍵}⌸ x[;2])⊣x←⍵[⍋⍵[;3];]}
```

And squeeze the result a little bit it would be identical to the solution I developed or went for a different method for simplification.

```
{⊃⊂⍤⊢⌸/↓⍉⍵[⍋⍵[;3];][;1 2]}
```

- Python (NumPy, SciPy), finding the null space of a matrix
- How can I convert a List<int[]> to a 2D array?
- locating a point in a 2d image that was warped
- Laravel Socialite dynamic server url for provider?
- Sort all matrix
- Fill With White, Out Of Bounds Part Of Image - Crop Image With CSS Transformations on it
- Multidimensional matrix permutation Julia vs. Python disagreement
- How to get the Q from the QR factorization output?
- Numpy element-wise addition with multiple arrays
- r dataframe and matrix result in different rownames when using rbind
- Python 3: Multiply a vector by a matrix without NumPy
- Fast way to set diagonals of an (M x N x N) matrix? Einsum / n-dimensional fill_diagonal?
- gnuplot create heatmap animation with matrix and image
- In Grafana How To Create and Fill a 2D matrix
- populating a matrix by rows
- Efficiently calculate an availability date from a list of project assignments and known capacity
- Corners detection fails when textbox is rotated
- Is there a way to MODIFY the diagonals (not just the centeral diagonal) of a matrix A by using just np.diag()?
- Find the linearly independent rows of a matrix
- Adding and removing columns in a matrix within a for loop
- Why is this matrix multiplication so slow?
- how to use a neural network to learn a matrix transformation?
- Using GEKKO to optimize two matrix/vector equations
- Recording the First Time an Event Happens
- Matrix elements sum
- Sum list of matrices with NAs
- The biggest spiral submatrix program written in C doesn't return what's expected
- matrix problem solving - find the first column that has a value 1 in a matrix of 1's and 0's
- DirectX distorted/stretched triangle render
- Defined a Set function to copy a variable-sized 2D square matrix but getting garbage