aboutsummaryrefslogtreecommitdiff
path: root/docs/doc/select.html
blob: 63a55e1e8ebc86718a969882f62011e9f652731c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
<head>
  <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/>
  <link href="../style.css" rel="stylesheet"/>
  <title>BQN: Select</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
<h1 id="select">Select</h1>
<svg viewBox='-148.8 -17.4 480 208.8'>
  <g font-family='BQN,monospace' font-size='22px' text-anchor='middle'>
    <rect class='code' stroke-width='1.5' rx='12' x='-96' y='0' width='374.4' height='174'/>
    <g class='lilac' stroke-width='2' stroke-linecap='round'>
      <line x1='88.32' x2='7.68' y1='46.4' y2='81.2'/>
      <line x1='48' x2='48' y1='46.4' y2='81.2'/>
      <line x1='51.84' x2='92.16' y1='46.4' y2='81.2'/>
      <line x1='232.32' x2='151.68' y1='46.4' y2='81.2'/>
      <line x1='0' x2='0' y1='104.4' y2='139.2'/>
      <line x1='48' x2='48' y1='104.4' y2='139.2'/>
      <line x1='96' x2='96' y1='104.4' y2='139.2'/>
      <line x1='144' x2='144' y1='104.4' y2='139.2'/>
    </g>
    <text dy='0.32em' x='0' y='34.8'><tspan class='String'>'s'</tspan></text>
    <text dy='0.32em' x='48' y='34.8'><tspan class='String'>'e'</tspan></text>
    <text dy='0.32em' x='96' y='34.8'><tspan class='String'>'l'</tspan></text>
    <text dy='0.32em' x='144' y='34.8'><tspan class='String'>'e'</tspan></text>
    <text dy='0.32em' x='192' y='34.8'><tspan class='String'>'c'</tspan></text>
    <text dy='0.32em' x='240' y='34.8'><tspan class='String'>'t'</tspan></text>
    <text dy='0.32em' x='0' y='92.8'><tspan class='Number'>2</tspan></text>
    <text dy='0.32em' x='48' y='92.8'><tspan class='Number'>1</tspan></text>
    <text dy='0.32em' x='96' y='92.8'><tspan class='Number'>1</tspan></text>
    <text dy='0.32em' x='144' y='92.8'><tspan class='Number'>5</tspan></text>
    <text dy='0.32em' x='0' y='150.8'><tspan class='String'>'l'</tspan></text>
    <text dy='0.32em' x='48' y='150.8'><tspan class='String'>'e'</tspan></text>
    <text dy='0.32em' x='96' y='150.8'><tspan class='String'>'e'</tspan></text>
    <text dy='0.32em' x='144' y='150.8'><tspan class='String'>'t'</tspan></text>
    <g fill='currentColor' font-size='12' opacity='0.75'>
      <text dy='0.32em' x='0' y='15.66'>0</text>
      <text dy='0.32em' x='48' y='15.66'>1</text>
      <text dy='0.32em' x='96' y='15.66'>2</text>
      <text dy='0.32em' x='144' y='15.66'>3</text>
      <text dy='0.32em' x='192' y='15.66'>4</text>
      <text dy='0.32em' x='240' y='15.66'>5</text>
    </g>
    <g font-size='18px' text-anchor='end'>
      <text dy='0.32em' x='-38.4' y='34.8'><tspan class='Value'>𝕩</tspan></text>
      <text dy='0.32em' x='-38.4' y='92.8'><tspan class='Value'>𝕨</tspan>  </text>
      <text dy='0.32em' x='-38.4' y='150.8'><tspan class='Value'>𝕨</tspan><tspan class='Function'>⊏</tspan><tspan class='Value'>𝕩</tspan></text>
    </g>
  </g>
</svg>

<p>The function Select (<code><span class='Function'>⊏</span></code>) reorganizes the array <code><span class='Value'>𝕩</span></code> along one or more axes based on <a href="indices.html">indices</a> given by <code><span class='Value'>𝕨</span></code>. The result has the same <a href="depth.html">depth</a> as <code><span class='Value'>𝕩</span></code>, since its elements are always elements of <code><span class='Value'>𝕩</span></code>. This means it differs from <a href="pick.html">Pick</a> (<code><span class='Function'>βŠ‘</span></code>), which takes elements from <code><span class='Value'>𝕩</span></code> but can arrange them in any nested structure, including returning an element directly.</p>
<p>The monadic form First Cell (<code><span class='Function'>⊏</span></code>) gets the major cell with index 0, so that <code><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> is identical to <code><span class='Number'>0</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code>.</p>
<h2 id="single-selection">Single selection</h2>
<p>Each axis of a BQN array is numbered starting at zero. Major cells are arranged along the first axis; in accordance with the <a href="leading.html">leading axis</a> principle, Select returns a major cell of <code><span class='Value'>𝕩</span></code> when <code><span class='Value'>𝕨</span></code> is an atom.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MiDiio8gImFiY2RlZiIgICMgQW4gZW5jbG9zZWQgZWxlbWVudAoKMiDiipEgImFiY2RlZiIgICMgUGljayBnZXRzIGEgbm9uLWVuY2xvc2VkIGVsZW1lbnQKCjIg4oqPID4ibnVsIuKAvyJvbmUi4oC/InR3byLigL8idHJlIuKAvyJmb3IiCgowIOKKjyA8NSAgIyBObyBmaXJzdCBheGlzIHRvIHNlbGVjdCBmcm9t">↗️</a><pre>    <span class='Number'>2</span> <span class='Function'>⊏</span> <span class='String'>&quot;abcdef&quot;</span>  <span class='Comment'># An enclosed element
</span>β”ŒΒ·   
Β·'c' 
    β”˜

    <span class='Number'>2</span> <span class='Function'>βŠ‘</span> <span class='String'>&quot;abcdef&quot;</span>  <span class='Comment'># Pick gets a non-enclosed element
</span>'c'

    <span class='Number'>2</span> <span class='Function'>⊏</span> <span class='Function'>&gt;</span><span class='String'>&quot;nul&quot;</span><span class='Ligature'>β€Ώ</span><span class='String'>&quot;one&quot;</span><span class='Ligature'>β€Ώ</span><span class='String'>&quot;two&quot;</span><span class='Ligature'>β€Ώ</span><span class='String'>&quot;tre&quot;</span><span class='Ligature'>β€Ώ</span><span class='String'>&quot;for&quot;</span>
"two"

    <span class='Number'>0</span> <span class='Function'>⊏</span> <span class='Function'>&lt;</span><span class='Number'>5</span>  <span class='Comment'># No first axis to select from
</span>ERROR
</pre>
<p>As a major cell of <code><span class='Value'>𝕩</span></code>, the result has rank one less than it and its shape is <code><span class='Number'>1</span><span class='Function'>↓≒</span><span class='Value'>𝕩</span></code>. <code><span class='Value'>𝕩</span></code> must have rank one or more.</p>
<p>The index <code><span class='Value'>𝕨</span></code> has to be an integer less than <code><span class='Function'>β‰ </span><span class='Value'>𝕩</span></code>. It can be negative, in which case it must be greater than or equal to <code><span class='Function'>-β‰ </span><span class='Value'>𝕩</span></code>. Negative indices select from the end of <code><span class='Value'>𝕩</span></code>, in that <code><span class='Number'>Β―1</span></code> indicates the last major cell and <code><span class='Function'>-β‰ </span><span class='Value'>𝕩</span></code> indicates the first. If <code><span class='Function'>β‰ </span><span class='Value'>𝕩</span></code> is 0, then no index is valid.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=wq8yIOKKjyAiYWJjZGVmIgoKMCDiio8gIiI=">↗️</a><pre>    <span class='Number'>Β―2</span> <span class='Function'>⊏</span> <span class='String'>&quot;abcdef&quot;</span>
β”ŒΒ·   
Β·'e' 
    β”˜

    <span class='Number'>0</span> <span class='Function'>⊏</span> <span class='String'>&quot;&quot;</span>
ERROR
</pre>
<p>The monadic case First Cell (<code><span class='Function'>⊏</span><span class='Value'>𝕩</span></code>) is identical to <code><span class='Number'>0</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code>. It has the same restrictions: <code><span class='Value'>𝕩</span></code> must have rank 1 or more, and length 1 or more (this differs from First (<code><span class='Function'>βŠ‘</span></code>), which removes the length requirement to return a fill element).</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqPICJhYmMiCgriio8gImFiYyLiiY0iZGVmIgoK4oqPIOKJjSAiYWJjIgoK4oqPICdhJw==">↗️</a><pre>    <span class='Function'>⊏</span> <span class='String'>&quot;abc&quot;</span>
β”ŒΒ·   
Β·'a' 
    β”˜

    <span class='Function'>⊏</span> <span class='String'>&quot;abc&quot;</span><span class='Function'>≍</span><span class='String'>&quot;def&quot;</span>
"abc"

    <span class='Function'>⊏</span> <span class='Function'>≍</span> <span class='String'>&quot;abc&quot;</span>
"abc"

    <span class='Function'>⊏</span> <span class='String'>'a'</span>
ERROR
</pre>
<h2 id="first-axis-selection">First-axis selection</h2>
<p>If <code><span class='Value'>𝕨</span></code> is an array of numbers (including any empty array), then each number indicates a major cell of <code><span class='Value'>𝕩</span></code>. In the simplest case, a list of numbers gives a result with the same rank as <code><span class='Value'>𝕩</span></code> but maybe not the same length.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MuKAvzPigL8z4oC/MOKAvzTigL8xIOKKjyAiT2xaRXQiCgrin6jin6kg4oqPICJPbFpFdCI=">↗️</a><pre>    <span class='Number'>2</span><span class='Ligature'>β€Ώ</span><span class='Number'>3</span><span class='Ligature'>β€Ώ</span><span class='Number'>3</span><span class='Ligature'>β€Ώ</span><span class='Number'>0</span><span class='Ligature'>β€Ώ</span><span class='Number'>4</span><span class='Ligature'>β€Ώ</span><span class='Number'>1</span> <span class='Function'>⊏</span> <span class='String'>&quot;OlZEt&quot;</span>
"ZEEOtl"

    <span class='Bracket'>⟨⟩</span> <span class='Function'>⊏</span> <span class='String'>&quot;OlZEt&quot;</span>
⟨⟩
</pre>
<p>To find the first and last cells of <code><span class='Value'>𝕩</span></code>, use <code><span class='Number'>0</span><span class='Ligature'>β€Ώ</span><span class='Number'>Β―1</span></code> for the left argument.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIG0g4oaQIDPigL814oC/N+KAvzExIHzijJwgw5fLnOKGlTcKCjDigL/CrzEg4oqPIG0=">↗️</a><pre>    <span class='Function'>⊒</span> <span class='Value'>m</span> <span class='Gets'>←</span> <span class='Number'>3</span><span class='Ligature'>β€Ώ</span><span class='Number'>5</span><span class='Ligature'>β€Ώ</span><span class='Number'>7</span><span class='Ligature'>β€Ώ</span><span class='Number'>11</span> <span class='Function'>|</span><span class='Modifier'>⌜</span> <span class='Function'>Γ—</span><span class='Modifier'>˜</span><span class='Function'>↕</span><span class='Number'>7</span>
β”Œβ”€               
β•΅ 0 1 1 0 1 1 0  
  0 1 4 4 1 0 1  
  0 1 4 2 2 4 1  
  0 1 4 9 5 3 3  
                β”˜

    <span class='Number'>0</span><span class='Ligature'>β€Ώ</span><span class='Number'>Β―1</span> <span class='Function'>⊏</span> <span class='Value'>m</span>
β”Œβ”€               
β•΅ 0 1 1 0 1 1 0  
  0 1 4 9 5 3 3  
                β”˜
</pre>
<p>More generally, <code><span class='Value'>𝕨</span></code> can be an array of any rank. Each of its 0-cellsβ€”containing a single numberβ€”is replaced with a cell of <code><span class='Value'>𝕩</span></code> in the result. The result's shape is then made up of the shape of <code><span class='Value'>𝕨</span></code> and the major cell shape of <code><span class='Value'>𝕩</span></code>: it's <code><span class='Paren'>(</span><span class='Function'>β‰’</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>∾</span><span class='Number'>1</span><span class='Function'>↓≒</span><span class='Value'>𝕩</span></code>.</p>
<p>When <code><span class='Value'>𝕩</span></code> is a list, the result has the same shape as <code><span class='Value'>𝕨</span></code>. Elements of <code><span class='Value'>𝕨</span></code> are replaced one-for-one with elements of <code><span class='Value'>𝕩</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MnxtCgooMnxtKSDiio8gIiAqIg==">↗️</a><pre>    <span class='Number'>2</span><span class='Function'>|</span><span class='Value'>m</span>
β”Œβ”€               
β•΅ 0 1 1 0 1 1 0  
  0 1 0 0 1 0 1  
  0 1 0 0 0 0 1  
  0 1 0 1 1 1 1  
                β”˜

    <span class='Paren'>(</span><span class='Number'>2</span><span class='Function'>|</span><span class='Value'>m</span><span class='Paren'>)</span> <span class='Function'>⊏</span> <span class='String'>&quot; *&quot;</span>
β”Œβ”€         
β•΅" ** **   
   *  * *  
   *    *  
   * ****" 
          β”˜
</pre>
<p>Another special case is when <code><span class='Value'>𝕨</span></code> is a unit. Now the result shape will be the major cell shape of <code><span class='Value'>𝕩</span></code>. In fact it's the same as the atom case above, that is, for a number <code><span class='Value'>n</span></code>, <code><span class='Paren'>(</span><span class='Function'>&lt;</span><span class='Value'>n</span><span class='Paren'>)</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> is the same as <code><span class='Value'>n</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code>.</p>
<p>The general case can result in a complicated array. Remember that the initial axes come from <code><span class='Value'>𝕨</span></code> while later ones come from <code><span class='Value'>𝕩</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ImF3QTAiICvijJwg4oaVNAoKMiDihpUg4oaVNAoKKDIg4oaVIOKGlTQpIOKKjyAiYXdBMCIgK+KMnCDihpU0">↗️</a><pre>    <span class='String'>&quot;awA0&quot;</span> <span class='Function'>+</span><span class='Modifier'>⌜</span> <span class='Function'>↕</span><span class='Number'>4</span>
β”Œβ”€      
β•΅"abcd  
  wxyz  
  ABCD  
  0123" 
       β”˜

    <span class='Number'>2</span> <span class='Function'>↕</span> <span class='Function'>↕</span><span class='Number'>4</span>
β”Œβ”€     
β•΅ 0 1  
  1 2  
  2 3  
      β”˜

    <span class='Paren'>(</span><span class='Number'>2</span> <span class='Function'>↕</span> <span class='Function'>↕</span><span class='Number'>4</span><span class='Paren'>)</span> <span class='Function'>⊏</span> <span class='String'>&quot;awA0&quot;</span> <span class='Function'>+</span><span class='Modifier'>⌜</span> <span class='Function'>↕</span><span class='Number'>4</span>
β”Œβ”€      
β•Ž"abcd  
  wxyz  
        
 Β·wxyz  
  ABCD  
        
 Β·ABCD  
  0123" 
       β”˜
</pre>
<h2 id="multi-axis-selection">Multi-axis selection</h2>
<p>Select also allows <code><span class='Value'>𝕨</span></code> to apply to multiple axes of <code><span class='Value'>𝕩</span></code> simultaneously. For this case, <code><span class='Value'>𝕨</span></code> must be a non-empty list (or unit array) where every element is an array of indices.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oMuKAvzEsIDPigL8w4oC/MOKfqSDiio8g4oaVM+KAvzQ=">↗️</a><pre>    <span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Ligature'>β€Ώ</span><span class='Number'>1</span><span class='Separator'>,</span> <span class='Number'>3</span><span class='Ligature'>β€Ώ</span><span class='Number'>0</span><span class='Ligature'>β€Ώ</span><span class='Number'>0</span><span class='Bracket'>⟩</span> <span class='Function'>⊏</span> <span class='Function'>↕</span><span class='Number'>3</span><span class='Ligature'>β€Ώ</span><span class='Number'>4</span>
β”Œβ”€                         
β•΅ ⟨ 2 3 ⟩ ⟨ 2 0 ⟩ ⟨ 2 0 ⟩  
  ⟨ 1 3 ⟩ ⟨ 1 0 ⟩ ⟨ 1 0 ⟩  
                          β”˜
</pre>
<p>Using a <a href="range.html">range</a> for <code><span class='Value'>𝕩</span></code> shows the structure of the selected elements more clearly, because each element is its own index. Each element of <code><span class='Value'>𝕨</span></code> acts independently, giving a structure like the <a href="map.html#table">Table</a> modifier.</p>
<p>While <code><span class='Value'>𝕨</span></code> must have rank one or less, its elements can have any rank. When the elements are units, the corresponding axis of <code><span class='Value'>𝕩</span></code> disappears from the result. We can select a 0-cell of <code><span class='Value'>𝕩</span></code> in this way, although the more common case of selecting an element is handled by <a href="pick.html">Pick</a>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oPDQsPDUsPDHin6kg4oqPICgz4qWKMTAp4qWK4oaVMWUzCuKfqCA0LCA1LCAx4p+pIOKKkSAoM+KlijEwKeKliuKGlTFlMw==">↗️</a><pre>    <span class='Bracket'>⟨</span><span class='Function'>&lt;</span><span class='Number'>4</span><span class='Separator'>,</span><span class='Function'>&lt;</span><span class='Number'>5</span><span class='Separator'>,</span><span class='Function'>&lt;</span><span class='Number'>1</span><span class='Bracket'>⟩</span> <span class='Function'>⊏</span> <span class='Paren'>(</span><span class='Number'>3</span><span class='Function'>β₯Š</span><span class='Number'>10</span><span class='Paren'>)</span><span class='Function'>β₯Šβ†•</span><span class='Number'>1e3</span>
β”ŒΒ·     
Β· 451  
      β”˜
    <span class='Bracket'>⟨</span> <span class='Number'>4</span><span class='Separator'>,</span> <span class='Number'>5</span><span class='Separator'>,</span> <span class='Number'>1</span><span class='Bracket'>⟩</span> <span class='Function'>βŠ‘</span> <span class='Paren'>(</span><span class='Number'>3</span><span class='Function'>β₯Š</span><span class='Number'>10</span><span class='Paren'>)</span><span class='Function'>β₯Šβ†•</span><span class='Number'>1e3</span>
451
</pre>
<p>However, the <code><span class='Function'>&lt;</span><span class='Modifier'>Β¨</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span></code> construct can select a cell of any rank from <code><span class='Value'>𝕩</span></code>, because <code><span class='Function'>β‰ </span><span class='Value'>𝕨</span></code> can be smaller than <code><span class='Function'>=</span><span class='Value'>𝕩</span></code> (okay, not quite: an empty list is always interpreted as a list of indices, so it's impossible to select the full-rank cell <code><span class='Value'>𝕩</span></code>). Below, <code><span class='Value'>𝕨</span></code> is missing one axis and the result is a 1-cell, or row, of <code><span class='Value'>𝕩</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oNCw14p+pIDzCqOKKuOKKjyAoM+KlijEwKeKliuKGlTFlMw==">↗️</a><pre>    <span class='Bracket'>⟨</span><span class='Number'>4</span><span class='Separator'>,</span><span class='Number'>5</span><span class='Bracket'>⟩</span> <span class='Function'>&lt;</span><span class='Modifier'>Β¨</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span> <span class='Paren'>(</span><span class='Number'>3</span><span class='Function'>β₯Š</span><span class='Number'>10</span><span class='Paren'>)</span><span class='Function'>β₯Šβ†•</span><span class='Number'>1e3</span>
⟨ 450 451 452 453 454 455 456 457 458 459 ⟩
</pre>
<p>If an element of <code><span class='Value'>𝕨</span></code> has rank more than 1, it increases the rank of <code><span class='Value'>𝕩</span></code> rather than decreasing it. The general rule is that in the result, one axis of <code><span class='Value'>𝕩</span></code> is replaced by all the axes of the corresponding element of <code><span class='Value'>𝕨</span></code> (trailing axes are unchanged). So the final shape <code><span class='Function'>β‰’</span><span class='Value'>𝕨</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> is <code><span class='Paren'>(</span><span class='Function'>βˆΎβ‰’</span><span class='Modifier'>Β¨</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>∾</span><span class='Value'>𝕨</span><span class='Function'>β‰ </span><span class='Modifier2'>⊸</span><span class='Function'>↓≒</span><span class='Value'>𝕩</span></code>. But this shape doesn't affect the elements retrieved from <code><span class='Value'>𝕩</span></code>. In all cases, using <code><span class='Function'>β₯Š</span><span class='Modifier'>Β¨</span><span class='Value'>𝕨</span></code> for the left argument and then <a href="reshape.html">reshaping</a> the result would yield the same value.</p>
<p>Selection only ever applies to leading axes of <code><span class='Value'>𝕩</span></code>. However, you can skip some leading axes using <code><span class='Modifier'>˘</span></code> or <code><span class='Modifier2'>βŽ‰</span></code>, to select on any contiguous set of axes. In particular, use the one-axis case <code><span class='Value'>𝕨</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span><span class='Modifier2'>βŽ‰</span><span class='Paren'>(</span><span class='Function'>-</span><span class='Value'>k</span><span class='Paren'>)</span> <span class='Value'>𝕩</span></code> to select along axis <code><span class='Value'>k</span></code> of <code><span class='Value'>𝕩</span></code>.</p>