The functions Indices and Replicate are used to copy or filter data. They might be described as transforming a run-length encoding into unencoded form. On the other hand, Indices might be described as giving a sparse representation of 𝕩, which is smaller if 𝕩 mostly consists of zeros.
BQN doesn't have any of the various features used in APL to add fills to the result of Replicate, like negative numbers in 𝕨 or an Expand (\) primitive. An alternative to Expand is to use Replicate with structural Under (⌾) to insert values into an array of fills.
Given a list of natural numbers 𝕨, Replicate repeats each major cell in 𝕩 the corresponding number of times. That is, 𝕨 and 𝕩 must have the same length, and the result includes i⊑𝕨 copies of each cell i⊏𝕩, in order.
2‿1‿0‿2 / "abcd" "aabdd" ⊢ a ← >"aa0"‿"bb1"‿"cc2"‿"dd3" ┌─ ╵"aa0 bb1 cc2 dd3" ┘ 2‿1‿0‿2 / a ┌─ ╵"aa0 aa0 bb1 dd3 dd3" ┘
It's also allowed for 𝕨 to be a single number (or enclosed number: it just needs to be a unit and not a list). In this case every cell of 𝕩 is repeated that number of times.
3 / "copy" "cccooopppyyy"
When 𝕨 is a list of booleans, a cell is never repeated more than once, meaning that each cell of 𝕩 is either left out (0), or kept in (1). If Fn is a function with a boolean result, Fn¨⊸/ filters elements of a list according to Fn.
1‿1‿0‿0‿1‿0 / "filter" "fie" ≤⟜'i' "filter" ⟨ 1 1 0 0 1 0 ⟩ ≤⟜'i'⊸/ "filter" "fie"
Here ≤⟜'i' is a pervasive function, so there's no need to add ¨. Similarly, to filter major cells of an array, Fn˘⊸/ could be used, applying Fn to one major cell at a time.
A similar pattern applies to Replicate as well. The function below tests which input characters are double quotes, but by adding one it changes the result to 1 for each non-quote character and 2 for quotes (but source code and display also double quotes here, so the input string has only two "s and the output has four).
{1+'"'=𝕩}⊸/ "for ""escaping"" quotes" "for """"escaping"""" quotes"
If 𝕨 has depth two, then its elements give the amounts to copy along each leading axis of 𝕩.
⊢ b ← 2‿5 ⥊ ↕10 ┌─ ╵ 0 1 2 3 4 5 6 7 8 9 ┘ ⟨2‿0, 1‿0‿0‿1‿1⟩ / b ┌─ ╵ 0 3 4 0 3 4 ┘ 2‿0 / 1‿0‿0‿1‿1⊸/˘ b ┌─ ╵ 0 3 4 0 3 4 ┘
Here the 2‿0 indicates that the first row of b is copied twice and the second is ignored, while 1‿0‿0‿1‿1 picks out three entries from that row. As in the single-axis case, 𝕩 can have extra trailing axes that aren't modified by 𝕨. The rules are that 𝕨 can't have more elements than axes of 𝕩 (so (≠𝕨)≤=𝕩), and that each element has to have the same length as the corresponding axis—or it can be a unit, as shown below.
⟨<2,<3⟩ / b ┌─ ╵ 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 ┘
Above, both elements of 𝕨 are enclosed numbers. An individual element doesn't have to be enclosed, but I don't recommend this, since if none of them are enclosed, then 𝕨 will have depth 1 and it will be interpreted as replicating along the first axis only.
⟨2,3⟩ / b ┌─ ╵ 0 1 2 3 4 0 1 2 3 4 5 6 7 8 9 5 6 7 8 9 5 6 7 8 9 ┘
The example above has a different result from the previous one! The function <¨⊸/ could be used in place of / to replicate each axis by a different number.
If 𝕨 is ⟨⟩, then it has depth 1, but is handled with the multidimensional case anyway, giving a result of 𝕩. The one-dimensional case could also only ever return 𝕩, but it would be required to have length 0, so this convention still only extends the simple case.
b ≡ ⟨⟩ / b 1
The monadic form of / is much simpler than the dyadic one, with no multidimensional case or mismatched argument ranks. 𝕩 must be a list of natural numbers, and /𝕩 is the list 𝕩/↕≠𝕩. Its elements are the indices for 𝕩, with index i repeated i⊑𝕩 times.
/ 3‿0‿1‿2 ⟨ 0 0 0 2 3 3 ⟩
A unit argument isn't allowed, and isn't very useful: for example, /6 might indicate an array of six zeros, but this can be written /⥊6 or 6⥊0 with hardly any extra effort.
When 𝕨 has rank 1, 𝕨/𝕩 is equivalent to 𝕨/⊸⊏𝕩. Of course, this isn't the only use of Indices. It also gets along well with Group: for example, /⊸⊔ groups 𝕩 according to a list of lengths 𝕨.
2‿5‿0‿1 /⊸⊔ "ABCDEFGH" ⟨ "AB" "CDEFG" ⟨⟩ "H" ⟩
This function will fail to include trailing empty arrays; the modification (/∾⟜1)⊸⊔ fixes this and ensures the result always has as many elements as 𝕨.
If 𝕩 is boolean then /𝕩 contains all the indices where a 1 appears in 𝕩. Applying -⟜» to the result gives the distance from each 1 to the previous, or to the start of the list, another potentially useful function.
/ 0‿1‿0‿1‿0‿0‿0‿0‿1‿0 ⟨ 1 3 8 ⟩ -⟜» / 0‿1‿0‿1‿0‿0‿0‿0‿1‿0 ⟨ 1 2 5 ⟩
With more effort we can also use / to analyze groups of 1s in the argument (and of course all these methods can be applied to 0s instead, by first flipping the values with ¬). First we highlight the start and end of each group by comparing the list with a shifted copy of itself. Or rather, we'll first place a 0 at the front and then at the end, in order to detect when a group starts at the beginning of the list or ends at the end (there's also a shift-based version, ≠⟜«0∾𝕩).
0 (∾≍∾˜) 0‿1‿1‿1‿0‿0‿1‿0‿1‿1‿0 ┌─ ╵ 0 0 1 1 1 0 0 1 0 1 1 0 0 1 1 1 0 0 1 0 1 1 0 0 ┘ 0 (∾≠∾˜) 0‿1‿1‿1‿0‿0‿1‿0‿1‿1‿0 ⟨ 0 1 0 0 1 0 1 1 1 0 1 0 ⟩ / 0(∾≠∾˜) 0‿1‿1‿1‿0‿0‿1‿0‿1‿1‿0 ⟨ 1 4 6 7 8 10 ⟩
So now we have the indices of each transition from 0 to 1 or 1 to 0, in an extended list with 0 added at the beginning and end. The first index has to be for a 0 to 1 transition, because we forced the first value to be a 0, and then the next can only be 1 to 0, then 0 to 1, and so on until the last, which must be 1 to 0 because the last value is also 0.
↗️-˜`˘ ∘‿2⥊/ 0(∾≠∾˜) 0‿1‿1‿1‿0‿0‿1‿0‿1‿1‿0 ┌─ ╵ 1 3 6 1 8 2 ┘
This means the transitions can be grouped exactly in pairs, the beginning and end of each group. Reshape with a computed length ∘‿2 groups these pairs, and then a scan -˜`˘ can be used to convert the start/end format to start/length if wanted.
The result of Indices /n is an ordered list of natural numbers, where the number i appears i⊑n times. Given an ordered list of natural numbers k, the inverse of indices returns a corresponding n: one where the value i⊑n is the number of times i appears in k.
/ 3‿2‿1 ⟨ 0 0 0 1 1 2 ⟩ /⁼ 0‿0‿0‿1‿1‿2 ⟨ 3 2 1 ⟩
Finding how many times each index appears in a list of indices is often a useful thing to do, and there are a few ways to do it:
↗️+˝˘ (↕5) =⌜ 2‿2‿4‿1‿2‿0 # Inefficient ⟨ 1 1 3 0 1 ⟩ ≠¨⊔ 2‿2‿4‿1‿2‿0 ⟨ 1 1 3 0 1 ⟩ /⁼∧ 2‿2‿4‿1‿2‿0 ⟨ 1 1 3 0 1 ⟩
For /⁼ to work, the argument has to be sorted: otherwise it won't be a valid result of /. But sorting with ∧ is no problem, and /⁼∧ will probably be faster than ≠¨⊔ in the absence of special handling for either combination.