# Nested arrays and trains


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

Read [Basics](01_basics.ipynb), [Functions](02_functions.ipynb), and
[Operators](03_operators.ipynb) first. An array is nested when at least
one of its items is itself an array. We’ll work with those items, then
combine functions without naming their arguments.

## Taking arrays apart

### `↑` (Up arrow)

#### monadic `↑` (First)

First returns the first item of a vector. For a string, that item is a
character.

``` bpl
"Word"
```

    Word

``` bpl
↑"Word"
```

    'W'

``` bpl
⍴↑"Word"
```

    ⍬ₓ

If the first item is an array, First returns that whole item. A matrix’s
rows are its major cells. First returns its first major cell.

``` bpl
↑[[1 2] [3 4 5]]
```

    1 2

``` bpl
↑[[1 [1 2] 3] 4]
```

    [1 [1 2] 3]

``` bpl
↑[0 1 2⋄3 4 5]
```

    0 1 2

First’s inverse chooses an enclosure holding its argument. An enclosure
is a scalar, an array of rank 0 with one item. The display marks it with
`⊂`. First returns that enclosed item.

``` bpl
↑⁻¹1 2 3
⍴↑⁻¹1 2 3
```

    ⊂[1 2 3]

    ⍬ₓ

#### dyadic `↑` (Take)

For a vector `⍵`, a positive count `⍺` takes its first `⍺` items.

``` bpl
4↑"Pineapple"
```

    Pine

If the magnitude of the count exceeds the vector’s length, Take adds
extra items called fill. For characters the fill is a space, and for
numbers it is zero.

``` bpl
12↑"Pineapple"
```

    Pineapple   

A negative count takes items from the end instead of the start.

``` bpl
¯5↑"Pineapple"
```

    apple

For higher-rank arrays, a single count takes major cells along the first
axis. Negative counts and padding work the same way.

``` 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↑mat
```

    0 1 2 3
    4 5 6 7

``` bpl
¯2↑mat
```

    4 5  6  7
    8 9 10 11

``` bpl
5↑mat
```

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

A vector of counts applies to successive axes. `2 ¯3↑mat` takes the
first two rows and the last three columns.

``` bpl
2 ¯3↑mat
```

    1 2 3
    5 6 7

### `↓` (Down arrow)

#### monadic `↓` (Split)

Split nests the vectors along the last axis. For a matrix it returns a
vector containing its rows. Parentheses with `⋄` between items, such as
`(1 2⋄3 4)`, display a vector of vectors.

``` 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
↓mat
⍴↓mat
```

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

    [3]ₓ

Split’s inverse joins these row vectors back into a matrix.

``` bpl
↓⁻¹↓mat
```

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

``` bpl
words←[["Hip"]⋄["Hop"]⋄["Dance"]]
words
```

      "Hip"
      "Hop"
    "Dance"

``` bpl
↓words
```

    ("Hip"⋄"Hop"⋄"Dance")

For a rank-3 array, Split keeps the first two axes and nests the vectors
along the last:

``` bpl
⍴↓2 3 4⍴⍳24
```

    [2 3]ₓ

#### dyadic `↓` (Drop)

For a vector `⍵`, a positive count `⍺` drops its first `⍺` items.

``` bpl
4↓"Pineapple"
```

    apple

``` bpl
12↓"Pineapple"
```

    ""

A negative count drops items from the end instead of the start.

``` bpl
¯5↓"Pineapple"
```

    Pine

For higher-rank arrays, a single count drops major cells along the first
axis.

``` bpl
mat
```

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

``` bpl
2↓mat
```

    8 9 10 11

A vector of counts drops along successive axes. `2 ¯3↓mat` removes the
first two rows and the last three columns.

``` bpl
2 ¯3↓mat
```

    8

## Nested items

### `⊂` (Left shoe)

#### monadic `⊂` (Enclose)

Enclose makes the scalar we met with First’s inverse. Start with a
vector of length 3:

``` bpl
1 2 3
```

    1 2 3

``` bpl
⍴1 2 3
```

    [3]ₓ

Enclosing the vector adds a layer. Its shape is now the empty vector,
because a scalar has no axes.

``` bpl
⊂1 2 3
```

    ⊂[1 2 3]

``` bpl
⍴⊂1 2 3
```

    ⍬ₓ

Enclose’s inverse removes the enclosure and returns its item, as First
does.

``` bpl
⊂⁻¹⊂1 2 3
```

    1 2 3

Brackets make nested vectors directly. `[1 [2 3]]` has two items,
whereas `⊂[1 [2 3]]` is a scalar holding that whole vector.

``` bpl
[1 [2 3]]
```

    [1 [2 3]]

``` bpl
⍴[1 [2 3]]
```

    [2]ₓ

Catenate takes the scalar’s one item, adding the whole nested vector:

``` bpl
1,⊂2 3
```

    [1 [2 3]]

``` bpl
⊂[1 [2 3]]
```

    ⊂[1 [2 3]]

``` bpl
⍴⊂[1 [2 3]]
```

    ⍬ₓ

Each Enclose adds another layer. First removes the outer enclosure.

``` bpl
⊂⊂[1 [2 3]]
↑⊂[1 [2 3]]
```

    ⊂⊂[1 [2 3]]

    [1 [2 3]]

A number such as `1` is an atom, not a scalar. Enclosing it creates a
scalar holding that number. They have the same rank but are different
values.

``` bpl
⊂1
⊂1 ≡ 1
```

    ⊂1

    $f

Arithmetic extends a scalar across a vector. Here each left-hand number
adds to the whole enclosed vector:

``` bpl
1 2 3+⊂4 5 6
```

    (5 6 7⋄6 7 8⋄7 8 9)

An atom extends too. Adding `1` adds to every item without adding
nesting:

``` bpl
1 2 3+1
```

    2 3 4

#### Enclosing a function

Write `ᵘ` after a function to enclose it. `+ᵘ` is a scalar holding Plus,
with an empty shape. First takes the function back out.

``` bpl
+ᵘ
⍴+ᵘ
↑+ᵘ
```

    +ᵘ

    ⍬ₓ

    +

#### dyadic `⊂` (Partitioned enclose)

Partitioned enclose splits an array into parts, called partitions. A
positive mark in the left argument starts a partition before that
position. Zeros continue the current partition. Here the marks at
positions 0 and 2 split the vector into two parts:

``` bpl
1 0 1 0 0 0 0⊂1 2 3 4 5 6 7
```

    (1 2⋄3 4 5 6 7)

The same marks split a string:

``` bpl
1 0 1 0 0 0 0⊂"HiEarth"
```

    "Hi" "Earth"

A mark greater than 1 starts that many partitions, putting empty
partitions before the one containing the item. Leading zeros leave out
the items before the first partition.

``` bpl
2 0 1 0 3 0⊂1 2 3 4 5 6
```

    [⍬ [1 2] [3 4] ⍬ ⍬ [5 6]]

``` bpl
1 0 2 0 0 0 0⊂"HiEarth"
```

    "Hi" "" "Earth"

With the marks fixed, Partitioned enclose’s inverse joins the parts. The
marks must reproduce those parts when applied again; leading omitted
items cannot be recovered.

``` bpl
1 0 1 0 0 0 0⊂⁻¹["Hi" "Earth"]
```

    HiEarth

### `⊆` (Left shoe underbar)

#### monadic `⊆` (Nest)

Nest encloses atoms and arrays whose items are all atoms. An array that
is already nested stays unchanged.

``` bpl
⊆1 ≡ ⊂1
```

    $t

``` bpl
⊆1 2 3 ≡ ⊂1 2 3
```

    $t

``` bpl
⊆[1 [1 2 3]] ≡ [1 [1 2 3]]
```

    $t

``` bpl
⊆[1 [1 2 3]]
[1 [1 2 3]]
```

    [1 [1 2 3]]

    [1 [1 2 3]]

``` bpl
⊂[1 [1 2 3]]
```

    ⊂[1 [1 2 3]]

Nest’s inverse removes a scalar’s enclosure. Other arrays stay
unchanged.

``` bpl
⊆⁻¹⊆1 2 3
⊆⁻¹[1 [2 3]]
```

    1 2 3

    [1 [2 3]]

#### dyadic `⊆` (Partition)

Partition starts a part at the first positive mark and whenever a mark
increases from the preceding one. A zero leaves out its item.

In the next example, zero marks exclude the spaces. Each rise from 0 to
1 starts the next word.

``` bpl
1 1 1 0 1 1 1 0 1 1 1 1⊆"How are you?"
```

    "How" "are" "you?"

``` bpl
1 1 2 2 2 2 2⊆"HiEarth"
```

    "Hi" "Earth"

``` bpl
1 1 2 2 2 0 0⊆"HiEarth"
```

    "Hi" "Ear"

A decrease in the markers does not start a new partition:

``` bpl
2 2 1 1 1 1 1⊆"HiEarth"
```

    ["HiEarth"]

Partition’s inverse joins the parts using the same marks. All marks must
be positive, because a zero would have discarded an item.

``` bpl
1 1 2 2 2 2 2⊆⁻¹["Hi" "Earth"]
```

    HiEarth

## Selecting and grouping

### `⊃` (Right shoe)

#### monadic `⊃` (Mix)

Mix turns a vector of vectors into a matrix, with one vector per row.

``` bpl
["Hip" "Hop"]
```

    "Hip" "Hop"

``` bpl
⊃["Hip" "Hop"]
```

    Hip
    Hop

``` bpl
⍴⊃["Hip" "Hop"]
```

    [2 3]ₓ

If the vectors have different lengths, Mix pads the shorter ones with
fill. For strings, the fill character is a space.

``` bpl
["Hip" "Hop" "Dance"]
```

    "Hip" "Hop" "Dance"

``` bpl
⊃["Hip" "Hop" "Dance"]
```

    Hip  
    Hop  
    Dance

``` bpl
⍴⊃["Hip" "Hop" "Dance"]
```

    [3 5]ₓ

Mix’s inverse splits a matrix into rows. Padding remains part of each
row.

``` bpl
⊃⁻¹⊃["Hip" "Hop" "Dance"]
```

    "Hip  " "Hop  " "Dance"

Items can be numbers or nested arrays. Mix assembles them into rows and
pads with zeros where needed.

``` bpl
[[6 4] 5 3]
⊃[[6 4] 5 3]
```

    [[6 4] 5 3]

    6 4
    5 0
    3 0

``` bpl
[[1 2] 3 [4 5 6]]
⊃[[1 2] 3 [4 5 6]]
```

    [[1 2] 3 [4 5 6]]

    1 2 0
    3 0 0
    4 5 6

#### dyadic `⊃` (Pick)

Pick selects inside arrays. For a vector, a single position selects an
item, counting from 0. Position 2 of `"Word"` is its third character.

``` bpl
2⊃"Word"
```

    'r'

If the selected item is an array, Pick returns that whole array.

``` bpl
1⊃[[1 2] [3 4 5]]
```

    3 4 5

A vector of positions defines a path through nested items. `1 0` selects
item 1, which is `3 4 5`, then item 0 of that vector, which is 3.

``` bpl
1 0⊃[[1 2] [3 4 5]]
```

    3

A path item can select several axes at once by listing one position for
each axis. The path `[[1 0]]` has one item, `1 0`, and selects row 1,
column 0.

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

    0 1 2
    3 4 5

``` bpl
[[1 0]]⊃mat
```

    3

Add another path item to select inside that result. Each item of this
matrix is a two-item vector with a string and a number. The path first
selects row 1, column 0, then item 0 of that vector.

``` bpl
G←[["ABC" 1] ["DEF" 2] ["GHI" 3]⋄["JKL" 4] ["MNO" 5] ["PQR" 6]]
G
```

    ["ABC" 1] ["DEF" 2] ["GHI" 3]
    ["JKL" 4] ["MNO" 5] ["PQR" 6]

``` bpl
[[1 0] 0]⊃G
```

    JKL

### `⌸` (Quad equal)

#### monadic `⌸` (Key operator)

Key groups equal values and calls its function operand on each group.
With one argument, that operand receives the group’s value as `⍺` and
its positions as `⍵`.

Catenate joins each character with its positions. In `"banana"`, `b` is
at position 0, `a` at positions 1, 3 and 5, and `n` at positions 2 and
4. The rows have different lengths, so their results are padded with
fill.

``` bpl
a←"banana"
```

``` bpl
,⌸a
```

    b 0ₓ      
    a 1ₓ 3ₓ 5ₓ
    n 2ₓ 4ₓ   

With two arguments, Key groups the right argument by the values on the
left. Here the right argument contains positions, and the dfn joins each
character with the sum of its positions.

``` bpl
a {⍺,+/⍵}⌸ ⍳≢a
```

    b 0ₓ
    a 9ₓ
    n 6ₓ

``` bpl
a ,⌸ ⍳≢a
```

    b 0ₓ      
    a 1ₓ 3ₓ 5ₓ
    n 2ₓ 4ₓ   

## Keys and named axes

A string key labels a position in an array, independently of the
grouping operator `⌸`. Write `key:value` items in brackets to make a
keyed vector, also called a record.

``` bpl
order←["price":10 "qty":2]
order
```

    ["price":10 "qty":2]

Pick accepts a key instead of a position. Writing `.price` after a
record reads its `"price"` item.

``` bpl
"price"⊃order
order.price
```

    10

    10

Arithmetic aligns the keys, even when their order differs:

``` bpl
["aa":1 "bb":2]+["bb":10 "aa":20]
```

    ["aa":21 "bb":12]

Dyadic `:` attaches keys to existing data. An axis can also have a name.
Here `city` and `month` name the two axes, while `NY`, `LA`, and the
month names label positions along them. The semicolon keeps each vector
of labels together.

``` bpl
axes←["city":"NY" "LA";"month":"Jan" "Feb" "Mar"]
sales←axes:[10 20 30⋄40 50 60]
sales
```

       Jan Feb Mar
    NY  10  20  30
    LA  40  50  60

Shape includes the axis names. Pick follows a path through the keys in
the usual way:

``` bpl
⍴sales
"LA" "Feb"⊃sales
```

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

    50

The Axis operator’s right operand can be an axis name. Sum across
`month` to get one total per city:

``` bpl
+/⍠"month" sales
```

    ["city":2]⍴["NY":60 "LA":150]

Monadic `:` removes keys. With the labels fixed on the left, its inverse
first checks that they match the array’s labels.

``` bpl
:sales
axes:⁻¹sales
```

    10 20 30
    40 50 60

    10 20 30
    40 50 60

See [Axis keys](../keyed.ipynb) for keyed selection, assignment, and
agreement between named axes.

## Keeping arguments and reading digits

### `⊢` (Right tack)

#### monadic `⊢` (Same)

Return the argument back unchanged

``` bpl
⊢1
```

    1

``` bpl
⊢"abc"
```

    abc

Same is its own inverse.

``` bpl
⊢⁻¹"abc"
```

    abc

#### dyadic `⊢` (Right)

Returns the right argument back unchanged

``` bpl
"abc"⊢1
```

    1

``` bpl
1⊢"abc"
```

    abc

Right’s inverse returns its right argument unchanged too.

``` bpl
3⊢⁻¹5
```

    5

### `⊣` (Left tack)

#### monadic `⊣` (Same)

Returns the argument back unchanged

``` bpl
⊣"abc"
```

    abc

This monadic form is also its own inverse.

``` bpl
⊣⁻¹"abc"
```

    abc

#### dyadic `⊣` (Left)

Returns the left argument back unchanged

``` bpl
"abc"⊣1
```

    abc

``` bpl
1⊣"abc"
```

    1

Left discards its right argument. Its inverse accepts a result matching
the fixed left argument and returns that result as one possible right
argument.

``` bpl
3⊣⁻¹3
```

    3

### `⊥` (Up tack)

#### monadic `⊥` (Binary decode)

Binary uses the digits 0 and 1 with place values 1, 2, 4, 8, and so on
from right to left. Decode reads these digits along the last axis.

``` bpl
⊥1 1 0 1
```

    13

Binary Decode’s inverse writes the binary digits instead of reading
them.

``` bpl
⊥⁻¹13
```

    1 1 0 1

#### dyadic `⊥` (Decode)

The left argument gives the base, the multiplier between adjacent place
values. `2⊥1 1 0 1` reads the digits as binary: 8 + 4 + 0 + 1, or 13.

``` bpl
2⊥1 1 0 1
```

    13

Different positions can use different bases. For hours, minutes, and
seconds, the two 60s mean 60 seconds per minute and 60 minutes per hour.
Decode does not use the first base, which we write as 0.

``` bpl
0 60 60⊥2 46 40
```

    10000

``` bpl
2×60×60 + 46×60 + 40
```

    10000

With mixed bases fixed on the left, Decode’s inverse writes one digit
for each base.

``` bpl
0 60 60⊥⁻¹10000
```

    2 46 40

Base 10 reads decimal digits:

``` bpl
10⊥1 1 0 1
```

    1101

``` bpl
10⊥3 4 1 6
```

    3416

A single fixed base makes the inverse choose enough digits for the
number.

``` bpl
10⊥⁻¹3416
```

    3 4 1 6

The base can be complex too:

``` bpl
1j1⊥1 2 3 4
```

    5ⱼ9

Base 1 adds the digits. `1⊥M` sums the rows of a matrix, like `+/M`.

``` bpl
1⊥3 1 4 1 5 9
```

    23

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

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

``` bpl
1⊥M
```

    6 22 38

### `⊤` (Down tack)

#### monadic `⊤` (Binary encode)

Encode writes binary digits, choosing enough positions for the number:

``` bpl
⊤5
```

    1 0 1

With several numbers, each row uses enough digits for the largest
number:

``` bpl
⊤5 7 12
```

    0 1 0 1
    0 1 1 1
    1 1 0 0

Binary Encode’s inverse reads the digits back into numbers.

``` bpl
⊤⁻¹1 0 1
```

    5

#### dyadic `⊤` (Encode)

The left argument lists the bases, one for each digit. Five decimal
positions leave a leading zero:

``` bpl
10 10 10 10 10⊤3658
```

    0 3 6 5 8

Three decimal positions keep only the last three digits. A zero base in
the first position keeps the leading part as one number:

``` bpl
10 10 10⊤3658
```

    6 5 8

``` bpl
0 10 10⊤3658
```

    36 5 8

Changing every base to 2 gives binary digits:

``` bpl
2 2 2 2⊤7
```

    0 1 1 1

Two positions keep only the last two binary digits:

``` bpl
2 2⊤7
```

    1 1

A vector of numbers becomes a matrix with one number’s digits in each
row. The digit axis is the last axis.

``` bpl
2 2 2 2⊤5 7 12
```

    0 1 0 1
    0 1 1 1
    1 1 0 0

Mixed bases convert 10000 seconds back to hours, minutes, and seconds:

``` bpl
0 60 60⊤10000
```

    2 46 40

With the bases fixed, Encode’s inverse reads digits in those bases.
Digits discarded by encoding are not recovered.

``` bpl
0 60 60⊤⁻¹2 46 40
10 10 10⊤⁻¹6 5 8
```

    10000

    658

## Trains

A run that ends in a function is a train. Three functions form a fork,
`f g h`, giving `(f x) g (h x)`. The middle function takes two
arguments. In mathematical notation, `(f+g)(x)=f(x)+g(x)` is one example
of this pattern.

For example, add the reciprocal of a number to its exponential:

``` bpl
÷3 + *3
```

    20.41887026

``` bpl
÷+* 3
```

    20.41887026

The fork applies both outer functions to 3 before adding their results.
A fork with Sum and Tally as its outer functions, and Divide in the
middle, computes the mean:

``` bpl
+/÷≢ 2 5 8 9
```

    6

``` bpl
mean←+/÷≢
```

``` bpl
mean 2 5 8 9
```

    6

A space before the argument separates the train from the call. `+/÷≢ x`
applies the mean function to `x`. Without that space, `+/÷≢x` reads as
`+/(÷(≢x))`.

With two arguments, a fork `f g h` gives `(a f b) g (a h b)`. Each outer
function receives both arguments. We can split a string at spaces by
using `≠` to mark its non-space characters and `⊢` to supply the string
itself.

``` bpl
' '≠"How are you?"
```

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

``` bpl
' '⊢"How are you?"
```

    How are you?

``` bpl
' '≠"How are you?" ⊆ ' '⊢"How are you?"
```

    "How" "are" "you?"

``` bpl
' '(≠⊆⊢)"How are you?"
```

    "How" "are" "you?"

Give the fork a name to reuse it:

``` bpl
split←≠⊆⊢
```

``` bpl
' ' split "How are you?"
```

    "How" "are" "you?"

A two-function train is an atop. `f g x` means `f(g x)`. For example,
`-|` takes the magnitude of its argument and then negates it:

``` bpl
-| 1 ¯2 3
```

    ¯1 ¯2 ¯3

[Previous: Operators and axes](03_operators.ipynb) · [Study
guide](../glyphs-study.qmd) · [Next: Searching and
indexing](05_searching-indexing.ipynb)
