From 632fdd3c713da19ae6e8e7b93078c838bcc06d9f Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Tue, 6 Jul 2021 14:28:45 -0400 Subject: Pick and First documentation --- docs/doc/index.html | 1 + docs/doc/pick.html | 129 ++++++++++++++++++++++++++++++++++++++++++++++++ docs/doc/primitive.html | 4 +- 3 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 docs/doc/pick.html (limited to 'docs') diff --git a/docs/doc/index.html b/docs/doc/index.html index 16511895..e32dd8f8 100644 --- a/docs/doc/index.html +++ b/docs/doc/index.html @@ -49,6 +49,7 @@
  • Match (≡≢)
  • Mapping (¨⌜)
  • Ordering functions (∧∨⍋⍒)
  • +
  • Pick ()
  • Prefixes and Suffixes (↑↓)
  • Range ()
  • Repeat ()
  • diff --git a/docs/doc/pick.html b/docs/doc/pick.html new file mode 100644 index 00000000..3f5495aa --- /dev/null +++ b/docs/doc/pick.html @@ -0,0 +1,129 @@ + + + + BQN: Pick + + +

    Pick

    +

    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.

    +

    With no 𝕨, monadic 𝕩 takes the first element of 𝕩 in index order, or its fill element if 𝕩 is empty (causing an error if no fill is known).

    +

    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.

    +

    One element

    +

    When the left argument is a number, Pick gets an element from a list:

    +↗️
        2  01234
    +2
    +    2  "abc"
    +'c'
    +    2  @, 0123, "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  01234
    +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. For convenience, a number is also allowed, but not an enclosed number (which could be confused with the nested case).

    +↗️
        2,0  45
    +⟨ 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' + (↕×´) 45
    +┌─       
    +╵"abcde  
    +  fghij  
    +  klmno  
    +  pqrst" 
    +        ┘
    +    20  a
    +'k'
    +    1¯1  a
    +'j'
    +
    +

    This applies even if 𝕩 is 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'
    +
    +

    First

    +

    With no left argument, is called First, and performs a slight generalization of Pick with a default left argument 0¨𝕩. For a non-empty array it returns the first element in index order.

    +↗️
         <'a'
    +'a'
    +     "First"
    +'F'
    +     4251
    +⟨ 0 0 0 0 ⟩
    +
    +

    If 𝕩 is empty then Pick always results in an error. First never gives an error: instead it returns the fill element for 𝕩.

    +↗️
         ""
    +' '
    +     π
    +0
    +     0↑<"  ",4
    +⟨ "  " ⟨ 0 0 0 0 ⟩ ⟩
    +
    +

    So one way to find the fill element for an array 𝕩 of any shape is 0𝕩.

    +

    In APL it's common to get the last element of a list with an idiom that translates to ⊑⌽, or First-Reverse. I prefer to use Fold with the Right identity function.

    +↗️
        ⊑⌽ "last"
    +'t'
    +    ´ "last"
    +'t'
    +
    +

    Many elements

    +

    Pick also accepts a list of indices:

    +↗️
        a  # Defined above
    +┌─       
    +╵"abcde  
    +  fghij  
    +  klmno  
    +  pqrst" 
    +        ┘
    +
    +    20, 1¯1, 31, ¯1¯1  a
    +"kjqt"
    +
    +

    These indices have to be lists, since if they're numbers it just looks like 𝕨 is one list index.

    +↗️
        2,1,0,¯1  "abc"  # 𝕩 doesn't have rank 4!
    +ERROR
    +
    +    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.

    +↗️
        20, ⟨⟨1¯1, 31, ¯1¯1⟩⟩  a
    +⟨ 'k' ⟨ "jq" 't' ⟩ ⟩
    +
    +    (20, 1¯131, ¯1¯1)  a
    +┌─    
    +╵"kj  
    +  qt" 
    +     ┘
    +
    +    (20, <1¯1<31, ¯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.

    +↗️
        (20, <1¯1<31, ¯1¯1) 1 a
    +┌─             
    +╵ 'k'   ┌·     
    +        ·'j'   
    +            ┘  
    +  ┌·    't'    
    +  ·'q'         
    +      ┘        
    +              ┘
    +
    +    ⟨⟨2,3,1  a  # 1 isn't a valid index
    +ERROR
    +
    diff --git a/docs/doc/primitive.html b/docs/doc/primitive.html index 638595d9..46f8d444 100644 --- a/docs/doc/primitive.html +++ b/docs/doc/primitive.html @@ -201,8 +201,8 @@ -First -Pick* +First +Pick* -- cgit v1.2.3