Pick (β
) chooses elements from π©
based on index lists from π¨
. π¨
can be a plain list, or even one number if π©
is a list, in order to get one element from π©
. It can also be an array of index lists, or have deeper array structure: each index list will be replaced with the element of π©
at that index, effectively applying to π¨
at depth 1.
The one-argument form is called First, and βπ©
takes the first element of π©
in index order, with an error if π©
is empty.
While sometimes "scatter-point" indexing is necessary, using Pick to select multiple elements from π©
is less array-oriented than Select (β
), and probably slower. Consider rearranging your data so that you can select along axes instead of picking out elements.
When the left argument is a number, Pick gets an element from a list:
βοΈ2 β 0βΏ1βΏ2βΏ3βΏ4 2 2 β "abc" 'c' 2 β β¨@, 0βΏ1βΏ2βΏ3, "abc"β© "abc"
A negative number π¨
behaves like π¨+β π©
, so that Β―1
will select the last element, and -β π©
the first. A number in π¨
must be an integer less than β π©
but not less than -β π©
.
Β―2 β 0βΏ1βΏ2βΏ3βΏ4 3 Β―2 β "abc" 'b'
Making π©
a list is only a special case. In general π¨
can be a list of numbers whose length is π©
's rank. So when =π©
is 1, π¨
can be length-1 list. The case above where π¨
is a number is a simplification, but an enclosed number π¨
isn't allowed because it could be confused with the nested case described below.
β¨2,0β© β β4βΏ5 β¨ 2 0 β©
Above we see that picking from the result of Range gives the index. For something slightly more interesting, here's a character array:
βοΈβ’ a β 'a' + β₯β(βΓΒ΄) 4βΏ5 ββ β΅"abcde fghij klmno pqrst" β 2βΏ0 β a 'k' 1βΏΒ―1 β a 'j'
π©
can even be a unit. By definition it has rank 0, so the only possible value for π¨
is the empty list. This extracts an enclosed element, and returns an atom unchangedβthe atom is promoted to an array by enclosing it, then the action of Pick undoes this. But there's rarely a reason to use this case, because the monadic form First accomplishes the same thing.
β¨β© β <'a' 'a' β¨β© β 'a' 'a'
With no left argument, β
is called First, and is the same as Pick with a default left argument 0Β¨β’π©
. For a non-empty array it returns the first element in index order.
β <'a' 'a' β "First" 'F' β β4βΏ2βΏ5βΏ1 β¨ 0 0 0 0 β©
And if π©
is empty then First results in an error.
β "" Error: β: Argument cannot be empty β β’Ο Error: β: Argument cannot be empty
In APL it's common to get the last element of a list with an idiom that translates to ββ½
, or First-Reverse. In BQN the most straightforward way is to select with index Β―1
instead. I also sometimes use Fold with the Right identity function.
ββ½ "last" 't' Β―1β "last" 't' β’Β΄ "last" 't'
Pick also accepts a list of indices:
βοΈa # Defined above ββ β΅"abcde fghij klmno pqrst" β β¨2βΏ0, 1βΏΒ―1, 3βΏ1, Β―1βΏΒ―1β© β a "kjqt"
These indices have to be lists, since if they're numbers it just looks like π¨
is an index list for one element.
β¨2,1,0,Β―1β© β "abc" # π© doesn't have rank 4! Error: β: Picking item at wrong rank (index 2βΏ1βΏ0βΏΒ―1 in array of shape β¨3β©) β¨2,1,0,Β―1β© β₯Β¨βΈβ "abc" "cbac" β¨2,1,0,Β―1β© β "abc" # Better way "cbac"
It's much more general than just a list of indices though. As long as your indices are lists, you can arrange them in any array structure with arbitrary nesting.
βοΈβ¨2βΏ0, β¨β¨1βΏΒ―1, 3βΏ1β©, Β―1βΏΒ―1β©β© β a β¨ 'k' β¨ "jq" 't' β© β© (β¨2βΏ0, 1βΏΒ―1β©ββ¨3βΏ1, Β―1βΏΒ―1β©) β a ββ β΅"kj qt" β (β¨2βΏ0, <1βΏΒ―1β©ββ¨<3βΏ1, Β―1βΏΒ―1β©) β a ββ β΅ 'k' βΒ· Β·'j' β βΒ· 't' Β·'q' β β
This option is easily described using the Depth modifier. Pick applies to depth-1 components of the left argument and the entire right argument, which corresponds to a depth operand of 1βΏβ
. The left argument components have to be lists of numbers, or Pick gives an error.
(β¨2βΏ0, <1βΏΒ―1β©ββ¨<3βΏ1, Β―1βΏΒ―1β©) ββ1βΏβ a ββ β΅ 'k' βΒ· Β·'j' β βΒ· 't' Β·'q' β β β¨β¨2,3β©,1β© β a # 1 isn't a valid index Error: β: π¨ contained list with mixed-type elements