larg ← larg (indx ##.merge axes) rarg       ⍝ Suggestion for a merge operator.
larg ← larg (indx ##.merge '∘' ) rarg

Classic APL lacks a general, non-procedural way to express: "THIS array but with
THOSE  items  at THESE positions". For example: "The letters of the alphabet but
with stars instead of vowels". Rather, it encourages us to use a 3-stage proced-
ure and to supply a name for the subject array:

    [1] Name the subject array,                             ⍝ THIS ← ⍵
    [2] Update the array, using its name,                   ⍝ THIS[THESE]←THOSE
    [3] Dereference the name for the result.                ⍝ THIS

(muse:

    Ideally, the language should never force us into naming the results of expr-
    essions. Better that we choose to name things only in order to create mental
    abstractions that are easier for us to work with. For example, the following
    three code fragments are equivalent and each reducible by the language eval-
    uator to the syntax tree on the right:

    (+/⍵)÷⍴⍵                                    ⍝
                                                ⍝        ┌───┼─┐
    sum←+/⍵ ⋄ num←⍴⍵  ⋄ sum÷num                 ⍝        ├─┐ ÷ ├─┐
                                                ⍝      ┌─┤ ⍵   ⍴ ⍵
    sum←+/ ⋄ num←⍴ ⋄ (sum ⍵)÷num ⍵              ⍝      + /
)

Operator [merge] merges the items of [rarg] into array [larg] at positions spec-
ified  by [indx]. In general, [indx] is a vector, whose shape is the same as the
rank  of  [larg].  Each item of [indx] may itself be a vector, in which case the
item  indicates  a number of positions along the corresponding axis, in the same
style as square-bracket and primitive ⌷ indexing.

If [axes] is supplied, it distributes the items of [indx] along the axes of larg
in the same manner as the primitive indexing fuction ⌷. This means that for axes
not  referenced  in the [axes] vector, all items are selected in the same way as
for missing subscripts when using square-bracket/semicolon indexing.

For example, if ⍺ is of rank 4 and index origin is 1, then:

        ⍺(i j k l merge'∘')⍵   ←~→   ⍺[i;j;k;l] ← ⍵
and
        ⍺(i j merge 3 2)⍵      ←~→   ⍺[;j;i;] ← ⍵

(muse:

    If  [merge]  were to be implemented as a primitive operator, the "axis case"
    could  use APL's regular axis operator. For example, suppose we chose "$" as
    the symbol for merge, then we might see expressions such as these:

        ⍺(v$)⍵          ⍝ merge with all axes selected: (⍴v)≡⍴⍴⍺.

        ⍺(v$[1 0])⍵     ⍝ merge with explicit axes: 2=⍴v.
)

Technical note:

[merge] may be implemented much more simply from Dyalog version 11.0 onwards, by
using the primitive index function together with selective specification:

    merge←{                         ⍝ Suggestion for a merge operator.
        ⍵⍵≡'∘':⍺(⍺⍺ ∇∇(⍳⍴⍴⍺))⍵      ⍝ default to all axes.
        0::⎕SIGNAL ⎕EN              ⍝ pass errors back to caller.
        A←⍺ ⋄ {A}(⍺⍺⌷[⍵⍵]A)←⍵       ⍝ merge using selective specification.  <V>
    }

Examples:

    vec←11 to 19                    ⍝ vector of numbers.

    vec
11 12 13 14 15 16 17 18 19

    vec(4 merge'∘') 0               ⍝ 4th item replaced with 0.
11 12 13 0 15 16 17 18 19

    vec((⊂3 4 5) merge'∘') 0        ⍝ 3rd-5th items replaced with 0s.
11 12 0 0 0 16 17 18 19

    vec((⊂4 3 2) merge'∘') 1 2 3    ⍝ 4th-2nd items replaced with 1-3.
11 3 2 1 15 16 17 18 19

    mat←10⊥¨⍳4 5                    ⍝ matrix of numbers.

    mat
11 12 13 14 15
21 22 23 24 25
31 32 33 34 35
41 42 43 44 45

    mat (2 merge 1) 0               ⍝ 2nd row replaced with 0s.
11 12 13 14 15
 0  0  0  0  0
31 32 33 34 35
41 42 43 44 45

    mat (4 merge 2) 0               ⍝ 4th col replaced with 0s.
11 12 13 0 15
21 22 23 0 25
31 32 33 0 35
41 42 43 0 45

    mat ((⊂2 3)merge 1) 0           ⍝ 2nd & 3rd rows replaced with 0s.
11 12 13 14 15
 0  0  0  0  0
 0  0  0  0  0
41 42 43 44 45

    mat ((⊂3 2)merge 1) 2 5⍴⍳10     ⍝ 3rd & 2nd rows replaced with numbers.
11 12 13 14 15
 6  7  8  9 10
 1  2  3  4  5
41 42 43 44 45

    mat ((2 3)(2 4)merge'∘')0       ⍝ 2nd 3rd rows, 2nd 4th cols ← 0.
11 12 13 14 15
21  0 23  0 25
31  0 33  0 35
41 42 43 44 45

    mat ((2 3)(2 4)merge'∘') 2 2⍴⍳4     ⍝   ..      ..      numbers.
11 12 13 14 15
21  1 23  2 25
31  3 33  4 35
41 42 43 44 45

    cube←10⊥¨⍳2 3 4                 ⍝ cuboid of numbers.

    cube
111 112 113 114
121 122 123 124
131 132 133 134

211 212 213 214
221 222 223 224
231 232 233 234

    cube (2 merge 1) 0              ⍝ 2nd plane replaced with 0s.
111 112 113 114
121 122 123 124
131 132 133 134

  0   0   0   0
  0   0   0   0
  0   0   0   0

    cube (2 merge 2) 0              ⍝ 2nd rows replaced with 0.
111 112 113 114
  0   0   0   0
131 132 133 134

211 212 213 214
  0   0   0   0
231 232 233 234

    cube (2 merge 3) 0              ⍝ 2nd cols replaced with 0s.
111 0 113 114
121 0 123 124
131 0 133 134

211 0 213 214
221 0 223 224
231 0 233 234

    cube (2 merge 1) 3 4⍴⍳12        ⍝ 2nd plane replaced with matrix.
111 112 113 114
121 122 123 124
131 132 133 134

  1   2   3   4
  5   6   7   8
  9  10  11  12

    cube (2 1 merge 1 3) ⍳3         ⍝ 2nd row, 1st col replaced with vector.
111 112 113 114
121 122 123 124
131 132 133 134

  1 212 213 214
  2 222 223 224
  3 232 233 234

    88 (⍬ merge '∘') 99             ⍝ scalar case.
99

⍝ Here's a handy derived function:

    first ← ⎕io merge ⎕io           ⍝ merge with first row (plane, ...).

    (4⍴⎕a) first '⍟'                ⍝ first item of vector.
⍟BCD

    (3 4⍴⎕a) first 'this'           ⍝ first row of matrix.
this
EFGH
IJKL
    (2 3 4⍴⎕a) first '⎕'            ⍝ first plane of cube.
⎕⎕⎕⎕
⎕⎕⎕⎕
⎕⎕⎕⎕

MNOP
QRST
UVWX

See also: squad mesh

Back to: contents

Back to: Dyalog APL

Trouble seeing APL font?