# Searching and indexing


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

Read [Nested arrays and trains](04_nested-arrays.ipynb) first.

## Membership and repeated values

### `∊` (Epsilon)

#### monadic `∊` (Enlist)

Enlist recursively collects all the atoms in nested arrays into one
vector.

``` bpl
mat←[0 1 2⋄3 4 5]
mat
```

    0 1 2
    3 4 5

``` bpl
∊[0 mat [7 8] "nine"]
```

    0 0 1 2 3 4 5 7 8 'n' 'i' 'n' 'e'

#### dyadic `∊` (Member of)

Membership tests whole items of a vector. Here neither `"ab"` nor
`"abcd"` matches the string `"abc"`.

``` bpl
["abc" 4]∊[4 "ab" "abcd"]
```

    $f $t

``` bpl
mat∊6 2 7 4
```

    $f $f $t
    $f $t $f

Against a vector, membership tests each item of the left argument.
Against a matrix, it tests each row:

``` bpl
[3 4 5⋄6 7 8]∊mat
```

    $t $f

### `⍷` (Epsilon Underbar)

#### dyadic `⍷` (Find)

Find marks the start of each occurrence of a pattern. Occurrences can
overlap, as in `"ana"` within `"Banana"`.

``` bpl
1⍷3 1 4 1 5 9 2
```

    $f $t $f $t $f $f $f

``` bpl
1 4⍷3 1 4 1 5 9 2
```

    $f $t $f $f $f $f $f

``` bpl
"ana"⍷"Banana"
```

    $f $t $f $t $f $f

A pattern can have more than one dimension:

``` bpl
pattern←[0 1⋄1 0]
board←[0 1 0 0⋄1 0 0 1⋄0 0 1 0⋄0 1 0 0]
[pattern board]
```

    [[0 1⋄1 0] [0 1 0 0⋄1 0 0 1⋄0 0 1 0⋄0 1 0 0]]

``` bpl
pattern⍷board
```

    $t $f $f $f
    $f $f $t $f
    $f $t $f $f
    $f $f $f $f

#### monadic `⍷` (Groups)

Groups gives the positions of each distinct major cell, in order of
first appearance:

``` bpl
⍷"Banana"
```

    (0⋄1 3 5⋄2 4)ₓ

The lengths of those groups count the occurrences:

``` bpl
≢¨⍷"Banana"
```

    [1 3 2]ₓ

### `∩` (Up shoe)

#### monadic `∩` (Duplicates)

Duplicates keeps one copy of each major cell that occurs more than once:

``` bpl
∩"mississippi"
```

    isp

#### dyadic `∩` (Intersection)

Intersection keeps the major cells of the left argument found in the
right argument. It preserves their order and repetitions.

``` bpl
"ABRA"∩"CAR"
```

    ARA

``` bpl
[22 "ab" "fg"]∩['a' "ab" 22]
```

    22 "ab"

### `∪` (Down shoe)

#### monadic `∪` (Unique)

Unique keeps the first of each distinct major cell:

``` bpl
a←2 3 4 2 3 4 5
```

``` bpl
∪a
```

    2 3 4 5

Unique mask followed by Replicate gives the same result:

``` bpl
(≠a)#a
```

    2 3 4 5

``` bpl
∪["ab" "ba" "ab" 1 1 2]
```

    "ab" "ba" 1 2

#### dyadic `∪` (Union)

Union appends the major cells of the right argument that are absent from
the left. Repetitions already present in either argument stay.

``` bpl
"ABRA"∪"CAR"
```

    ABRAC

``` bpl
[22 "ab" "fg"]∪['a' "ab" 22]
```

    22 "ab" "fg" 'a'

## Sort / index

### `⌷` (Squad)

#### monadic `⌷` (Materialise)

`⌷Y` returns `Y` unchanged.

Its inverse also leaves the argument unchanged:

``` bpl
⌷⁻¹1 2 3
```

    1 2 3

#### dyadic `⌷` (Index)

Indexing reads items at chosen positions. Those items form a selection.
Each item of `⌷`’s left argument selects along one axis, starting with
axis 0. A vector of positions for a single axis is one item, hence the
nested brackets in `[[3 5]]`.

``` bpl
v←2×⍳12
3⌷v
```

    6

``` bpl
[[3 5]]⌷v
```

    6 10

``` bpl
mat←[0 1 2 3⋄4 5 6 7⋄8 9 10 11]
mat
```

    0 1  2  3
    4 5  6  7
    8 9 10 11

``` bpl
2 3⌷mat
```

    11

With two vectors, `⌷` takes every combination of the selected rows and
columns:

``` bpl
[0 2;1 3]⌷mat
```

    1  3
    9 11

### Bracket indexing

A dot before the brackets makes a selection. Positions count from 0;
negative positions count from the end:

``` bpl
v.[3]
```

    6

The outer brackets contain one index per axis. To select several
positions along one axis, put a vector inside them:

``` bpl
v.[[3 5]]
```

    6 10

`.[]` pairs its index arrays, rather than taking every combination. The
same row and column positions now read two items:

``` bpl
mat.[[0 2] [1 3]]
```

    1 11

#### Digit subscripts

A digit subscript selects one major cell along axis 0. `v₁` is `v.[1]`,
and a negative subscript counts from the end. Consecutive digits form
one position: `₁₂` selects position 12, and `₋₁₂` counts twelve places
from the end. On a matrix it selects a row. A dot followed by a digit is
a decimal point, so use `v.[2]` or `v₂` for position 2:

``` bpl
v←10 20 30 40 50
[v₁ v₋₁]
```

    20 50

``` bpl
mat₁
```

    4 5 6 7

A subscript attaches to the preceding item before surrounding functions
apply. Sum reads row 1 before adding its items. In `v₁²`, item 1 is
selected and then squared:

``` bpl
+/mat₁
```

    22

``` bpl
v₁²
```

    400

After a space, the subscript selects from the whole run on its left. It
must stand alone, with a space on each side:

``` bpl
10 20 30 ₁
```

    20

``` bpl
,mat ₁
```

    1

An atom or scalar has no axis for a digit subscript. Use a subscript
only when that position exists in an array.

#### Whole axes and new axes

Axes omitted at the end stay whole. A single position removes its axis,
while an array of positions replaces that axis with the index array’s
shape. Paired index arrays occupy the first index array’s place in the
result, and whole axes keep their places:

``` bpl
mat.[1]
```

    4 5 6 7

``` bpl
⍴mat.[[[0 1]⋄[1 2]]]
```

    [2 2 4]ₓ

`:` takes one whole axis. Here the rows stay whole and columns 1 and 3
are selected:

``` bpl
mat.[: [1 3]]
```

    1  3
    5  7
    9 11

Keep `:` as a separate item, as in `mat.[: 1]`.

`∞` takes all remaining axes at that position. At most one `∞` is
allowed. Here it keeps both axes, so the result is `mat`:

``` bpl
mat.[∞]
```

    0 1  2  3
    4 5  6  7
    8 9 10 11

A selector after `∞` applies at the end. Here `∞` keeps the rows and `1`
selects the last axis’s column 1:

``` bpl
mat.[∞ 1]
```

    1 5 9

An empty bracket list omits every axis, keeping the array unchanged:

``` bpl
mat.[]
```

    0 1  2  3
    4 5  6  7
    8 9 10 11

`¯∞` inserts a new unnamed axis of length 1, without consuming an input
axis. Its position in the brackets decides where it goes:

``` bpl
⍴mat.[: ¯∞ :]
```

    [3 1 4]ₓ

``` bpl
⍴mat.[∞ ¯∞]
```

    [3 4 1]ₓ

#### Pairing and coordinates

Index arrays agree in shape as arithmetic arguments do. This selects
column 2 from row 0, column 0 from row 1 and column 3 from row 2:

``` bpl
mat.[⍳3ₓ [2 0 3]]
```

    2 4 11

Repeating the same index array selects a diagonal, with row and column
positions equal:

``` bpl
i←⍳3ₓ
mat.[i i]
```

    0 5 10

A coordinate lists positions along successive axes, such as `[0 1]` for
row 0, column 1. An array of coordinates reads the item or cell at each.
Where gives coordinates for a condition on a matrix:

``` bpl
where←⍸mat>8
where
```

    (2 1⋄2 2⋄2 3)ₓ

``` bpl
mat.[where]
```

    9 10 11

A coordinate array consumes the axes each coordinate covers. Any further
index arrays pair with it. In this rank-3 array, two coordinates select
rows, and the last index gives a column for each row:

``` bpl
cube←2 3 4⍴⍳24
coords←[[0 1] [1 2]]
cube.[coords [3 0]]
```

    7 20

A path can continue into nested items, as Pick does. These paths select
item 2 of item 1 and item 0 of item 0:

``` bpl
nested←[10 20;30 40 50]
nested.[[[1 2] [0 0]]]
```

    50 10

Each path must end at a cell of the same shape. After paths go into
nested items, `:`, `∞` and `¯∞` can keep or add axes of those cells:

``` bpl
nested←[[1 2 3⋄4 5 6] [7 8 9⋄10 11 12]]
paths←[[0 1] [1 0]]
nested.[paths]
```

    4 5 6
    7 8 9

``` bpl
⍴nested.[paths ∞ ¯∞]
```

    [2 3 1]ₓ

#### Keys and dotted paths

A string selects a key. `.name` reads the literal key `"name"`; brackets
can compute a key from a variable or expression. Dotted paths continue
from left to right through nested records:

``` bpl
rec←["price":10 "qty":2 "address":["city":"LA"]]
rec.address.city
```

    LA

``` bpl
field←"qty"
rec.[field]
```

    2

``` bpl
rec.["pr","ice"]
```

    10

`T.(expression)` evaluates an expression with `T`’s keys as names. A
key’s name takes precedence over an outer name with the same spelling.
Other names still refer to their surrounding definitions. Assignments
inside the parentheses stay there, leaving `T` unchanged:

``` bpl
rec.(price×qty)
```

    20

With keys on a matrix’s first axis, each name stands for a whole major
cell:

``` bpl
table←"left" "right":[1 2 3⋄4 5 6]
table.(left+right)
```

    5 7 9

``` bpl
rate←0.5
rec.(price×rate)
```

    5

``` bpl
rec.(price←3)
rec.price
```

    3

    10

A name read by a key can hold a function too. After a function, however,
a dot before another function makes an inner product, as in `+.×`.

``` bpl
ops←["double":2×]
ops.double 3
```

    6

Keep a space before the argument when calling a function through a
field. `ops.double3` would read the key `"double3"`.

#### Function-result selections and binding

After a function, `.name` and `.[...]` select from its result. Same,
`⊢`, returns its argument unchanged, so these read its fields and
positions. The suffix also works after a dyadic function:

``` bpl
⊢.address.city rec
```

    LA

``` bpl
⊢.[[1 3]] v
```

    20 40

``` bpl
1 2 3 4 5 +.[[0 2]] v
```

    11 33

A vector of records can be read field by field with Each. To evaluate an
expression for every record, apply a dfn with Each; `T.(...)` itself
binds the keys on `T`’s first axis, rather than mapping over records:

``` bpl
orders←[rec ["price":5 "qty":3]]
⊢.price¨orders
```

    10 5

``` bpl
{⍵.(price×qty)}¨orders
```

    20 15

Dotted paths and subscripts bind more tightly than functions.
`2×rec.price` doubles the price, and `rec.address.city₁` reads character
1 of the city. A path is read left to right, with the array evaluated
before its index:

``` bpl
2×rec.price
```

    20

``` bpl
rec.address.city₁
```

    'A'

#### Named indices

An index array can have a named axis. Indices with the same axis name
pair; indices with different names keep separate axes and build every
combination:

``` bpl
r←⍳["r":3] ⋄ c←⍳["c":4]
mat.[r c]
```

    0 1  2  3
    4 5  6  7
    8 9 10 11

A named index that appears alone for its name selects the data axis with
that name, wherever it stands in the brackets. Axis-qualified Iota gives
an index with the axis’s name and keys:

``` bpl
sales←["city":"NY" "LA";"month":"Jan" "Feb" "Mar"]:[10 20 30⋄40 50 60]
cy←⍳⍠"city" sales ⋄ mo←⍳⍠"month" sales
sales≡sales.[mo cy]
```

    $t

Strings select keys on any axis, and can mix with positions:

``` bpl
sales.[1 "Feb"]
```

    50

A single string removes its axis. A one-item vector of strings keeps
that axis, with length 1:

``` bpl
⍴sales.["LA"]
```

    ["month":3]ₓ

``` bpl
⍴sales.[["LA"]]
```

    ["city":1 "month":3]ₓ

When several selectors share a name, they pair and take the data’s axes
in order instead. Both selectors below have the name `"col"`: one gives
a row for each column, and the other gives the column:

``` bpl
data←["row":3 "col":4]⍴mat
cols←⍳["col":4] ⋄ rows←["col":4]⍴2 0 1 2
data.[rows cols]
```

    ["col":4]⍴[8 1 6 11]

#### Reading fill and changing selections

Numeric positions must be whole numbers. A position outside an axis is
an Index error. NaN means “not a number”, written `$n`; as a position it
reads fill instead, zero for these numbers. Negative positions still
count from the end:

``` bpl
v.[[¯1 $n 0]]
```

    50 0 10

An assignment through a selection changes the original array. A single
selection stores the whole value, while a vector selection replaces its
selected items. Subscripts can be targets too, but a spaced subscript
cannot:

``` bpl
v₁←5
v
```

    10 5 30 40 50

Modified assignment, such as `+←`, adds to the existing values instead
of replacing them. It applies once for each appearance of a repeated
position. A NaN position writes nothing:

``` bpl
v.[[1 3 1 $n]]+←1
v
```

    10 7 30 41 50

``` bpl
v₁+←1
v
```

    10 8 30 41 50

Plain assignment to a repeated position keeps its last replacement:

``` bpl
v.[[0 0 $n]]←7 8 99
v
```

    8 8 30 41 50

Index with `⌷` writes a block instead of pairing its indices. The space
before `←` makes the whole run on its left the target. A dotted target
already holds its selection together:

``` bpl
grid←3 4⍴0
[0 2;1 3]⌷grid +←10
grid
```

    0 10 0 10
    0  0 0  0
    0 10 0 10

Plain assignment through a missing key adds it, and creates missing
records along a dotted path. Reading a missing key, modifying a missing
key or writing past the end by position is an Index error:

``` bpl
rec.style.color←"red"
rec.style
```

    ["color":"red"]

``` bpl
rec.price+←2
rec.price
```

    12

``` bpl
sales.["SF"]←70 80 90
sales.[: "Apr"]←1 2 3
sales
```

       Jan Feb Mar Apr
    NY  10  20  30   1
    LA  40  50  60   2
    SF  70  80  90   3

Adding a row and column together fills the other new cells with zero:

``` bpl
sales.["TX" "May"]←9
sales
```

       Jan Feb Mar Apr May
    NY  10  20  30   1   0
    LA  40  50  60   2   0
    SF  70  80  90   3   0
    TX   0   0   0   0   9

A vector selection aligns replacement keys with its kept axis. Here the
replacement gives the names in reverse order, but each new price goes to
its own key. A single key selection instead stores the whole right
argument as that item’s value:

``` bpl
prices←["aa":1 "bb":2]
prices.[["aa" "bb"]]←["bb":20 "aa":10]
prices
```

    ["aa":10 "bb":20]

``` bpl
prices.["aa"]←[7 8]
prices.aa
```

    7 8

Repeated positions are allowed on unkeyed axes. A selection that repeats
a key is a Domain error, because an axis cannot have duplicate keys.

### `⍒` (Grade Down)

#### monadic `⍒` (Grade Down)

Grade down gives the positions that would put the major cells in
descending order. Reading those positions sorts the array, as `>` does
directly.

``` bpl
⍒33 11 44 66 22
```

    [3 2 0 4 1]ₓ

``` bpl
a←33 11 44 66 22
```

``` bpl
a.[⍒a]
```

    66 44 33 22 11

``` bpl
[⍒a]⌷a
```

    66 44 33 22 11

``` bpl
>a
```

    66 44 33 22 11

Grade is useful when we sort one array by another. Here the names go in
order of decreasing score:

``` bpl
names←"Sue" "Ali" "Bo"
scores←75 92 83
[⍒scores]⌷names
```

    "Ali" "Bo" "Sue"

The inverse needs a permutation: the positions from 0 to one less than
the length, each used once. It returns one vector whose Grade down is
that permutation, rather than recovering the original values:

``` bpl
ranks←⍒⁻¹⍒a
ranks
```

    [2 0 3 4 1]ₓ

``` bpl
⍒ranks
```

    [3 2 0 4 1]ₓ

#### dyadic `⍒` (Dyadic Grade Down)

A character left argument gives a custom alphabet. Here `c`, then `g`,
then `f` have increasing positions in that alphabet. Unlisted characters
share a position after the listed ones. Grade down puts these positions
in reverse order:

``` bpl
a←"abcdefgabcdefg"
```

``` bpl
b←"cgf"⍒a
```

``` bpl
[b]⌷a
```

    abdeabdeffggcc

### `⍋` (Grade Up)

#### monadic `⍋` (Grade Up)

Grade up gives positions in ascending order. Ties keep their original
order.

``` bpl
⍋33 11 44 66 22
```

    [1 4 0 2 3]ₓ

``` bpl
a←33 11 44 66 22
```

``` bpl
a.[⍋a]
```

    11 22 33 44 66

``` bpl
[⍋a]⌷a
```

    11 22 33 44 66

Grade up’s inverse likewise turns a permutation into a vector having
that grade:

``` bpl
ranks←⍋⁻¹⍋a
ranks
```

    [2 0 3 4 1]ₓ

``` bpl
⍋ranks
```

    [1 4 0 2 3]ₓ

#### dyadic `⍋` (Dyadic Grade Up)

With a custom alphabet, Grade up puts `c`, `g`, then `f` first:

``` bpl
a←"abcdefgabcdefg"
b←"cgf"⍋a
[b]⌷a
```

    ccggffabdeabde

#### Sorting each column

A grade along a named axis keeps the other axis names. Here each column
gets its own row positions. As a selector, the `"row"` axis selects rows
and the `"col"` axis pairs those positions with the matching columns:

``` bpl
scores←["row":3 "col":4]⍴[3 1 4 1⋄5 9 2 6⋄5 3 5 8]
grades←⍋⍠"row" scores
grades
```

    [0 0 1 0
     1 2 0 1
     2 1 2 2]ₓ

``` bpl
scores.[grades]
```

    3 1 2 1
    5 3 4 6
    5 9 5 8

[Previous: Nested arrays and trains](04_nested-arrays.ipynb) · [Study
guide](../glyphs-study.qmd) · [Next: Rearranging and transforming
arrays](06_rearranging-arrays.ipynb)
