The basic idea of Take (β
) is to get the first few elements of a list, while Drop (β
) removes those and returns the rest. Then they are extended in like a billion ways.
π©
can be an atom, or array of any rank (the result will be an array).π¨
can be negative to take or drop from the end instead of the beginning.π¨
is larger than the length of π©
, then fills are added.π¨
can have multiple numbers corresponding to leading axes of π©
.π¨
is allowed to be longer than the rank of π©
; π©
will be extended to fit.These extensions can be combined as well, so there are a lot of possibilities. A good picture to have in mind is cutting out a corner of the array π©
. This is because the result π¨βπ©
or π¨βπ©
always aligns with one side of π©
along each axis, so it also aligns with the corner where those sides meet.
The result dβπ©
is always the same as tβπ©
for some other argument t
, but computing t
wouldn't be too convenient. The reverse isn't true: only Take can insert fills, so results that include them can't come from Drop.
Let's start with a natural number π¨
. Take gives the first π¨
major cells of π©
(or elements of a list), while Drop gives all but the first π¨
.
4 β "take and drop" "take" 4 β "take and drop" " and drop" 1 β >"maj"βΏ"orc"βΏ"ell" ββ β΅"orc ell" β
If π¨
is too large it's usually not a problem. For Take, fill elements are added to the end to bring π©
up to the required lengthβalthough this will fail if π©
has no fill element. For Drop, the result is an empty array.
β6 β¨ 0 1 2 3 4 5 β© 10 β β6 β¨ 0 1 2 3 4 5 0 0 0 0 β© 10 β β6 β¨β© β’ 5 β β3βΏ9βΏ2 β¨ 0 9 2 β©
If π©
is an atom or unit array, it's converted to a list first. For Take this is useful to make an array of mostly fills; for Drop it's pretty much useless.
10 β 9 β¨ 9 0 0 0 0 0 0 0 0 0 β© 3 β <"element" β¨β©
If π¨
is negative, it wraps around the other side to take or drop from the end of π©
. It's a lot like negative indices in Select (β
), but while negative indices are asymmetricβ0
is the first entry but Β―1
is the lastβthis case is symmetric. It's because the place to cut is always before the index π¨
, cancelling out the negative index asymmetry.
3 β "abcdeEDCBA" "abc" Β―3 β "abcdeEDCBA" # Last three "CBA" Β―3 β "abcdeEDCBA" # All but the last three "abcdeED"
What about 0
? It behaves like it's both positive and negative. For Take, the first 0 and last 0 cells are indistinguishable, because they're both empty. For Drop, if you remove 0 cells it doesn't matter whether you start at the front or the back, because you're not going to do anything either way.
0 β 4βΏ3βΏ2 # Nothing β¨β© 0 β 4βΏ3βΏ2 # Everything β¨ 4 3 2 β©
If |π¨
is too large, then Take will insert fills at the beginning to keep the result aligned with π©
at the end. Drop returns an empty array as in the positive case. So unlike Rotate (β½
), which is completely cyclical, Take and Drop look cyclic only around 0.
Β―6 β "xy" " xy"
In the general case π¨
is a list of integers. They're matched with the leading axes of π©
, so that each affects one axis independently from the others.
β’ m β (10Γβ5) +β β7 ββ β΅ 0 1 2 3 4 5 6 10 11 12 13 14 15 16 20 21 22 23 24 25 26 30 31 32 33 34 35 36 40 41 42 43 44 45 46 β Β―4βΏ2 β m # Last four rows; first two columns ββ β΅ 10 11 20 21 30 31 40 41 β Β―4βΏ2 β m ββ β΅ 2 3 4 5 6 β
Now Take and Drop taken together don't include the whole array. Take includes the elements that are selected on every axis, while Drop excludes the ones selected on any axis. They are opposite corners that meet at some point in the middle of the array (here, at the spot between 2
and 11
).
Any integer values at all can be used, in any combination. Here one axis is shortened and the other's padded with fills. The result of Take has shape |π¨
, maybe plus some trailing axes from π©
. Of course, if that's too big for your available memory, your BQN implementation probably can't compute it for you!
3βΏΒ―12 β m ββ β΅ 0 0 0 0 0 0 1 2 3 4 5 6 0 0 0 0 0 10 11 12 13 14 15 16 0 0 0 0 0 20 21 22 23 24 25 26 β β’ 9βΏΒ―4 β β7βΏ6βΏ5 # Trailing shape example β¨ 9 4 5 β©
If the rank of π©
is smaller than the length of π¨
, then length-1 axes are added to the beginning until it's equal. Mostly this will be used with Take when π©
is a unit, producing an array that contains π©
and a lot of fills.
3βΏ4 β <1βΏ1 ββ β΅ β¨ 1 1 β© β¨ 0 0 β© β¨ 0 0 β© β¨ 0 0 β© β¨ 0 0 β© β¨ 0 0 β© β¨ 0 0 β© β¨ 0 0 β© β¨ 0 0 β© β¨ 0 0 β© β¨ 0 0 β© β¨ 0 0 β© β
This property also enables a nice little trick with Drop. If π¨
is a list of zeros, Drop won't do anythingβexcept extend the rank of π©
. So (rβ₯0)βa
, or r β₯β0βΈβ a
, ensures a
is an array with rank at least r
but doesn't change any of the elements. As a special case, β¨β©βv
Encloses an atom argument but otherwise has no effect.
β’ (3β₯0) β 3 β¨ 1 1 1 β© β’ (3β₯0) β β3 β¨ 1 1 3 β© β’ (3β₯0) β β5βΏ4βΏ3βΏ2 β¨ 5 4 3 2 β©