Skip to content

. @ Amend, Amend At

Modify one or more items in a list, dictionary or datafile.

Amend             Amend At         values (d . i) or (d @ i) become

.[d; i; u]        @[d; i; u]       u[d . i]       u'[d @ i]
.[d; i; v; vy]    @[d; i; v; vy]   v[d . i;vy]    v'[d @ i;vy]

Where

  • d is an atom, list, or a dictionary (value); or a handle to a list, dictionary or datafile
  • i is a list of the indexes of d to be amended:
    • if empty (for .) or the general null :: (for @), or if d is a non-handle atom, the selection S is d (Amend Entire)
    • otherwise S is .[d;i] or @[d;i]
  • u is a unary
  • v is a binary, and vy is
    • in the right domain of v
    • unless S is d, conformable to S and of the same type

the items in d of the selection S are replaced

  • in the ternary, by u[S] for . and by u'[S] for @
  • in the quaternary, by v[S;vy] for . and by v'[S;vy] for @

and if d is a

  • value, returns a copy of it with the item/s at i modified
  • handle, modifies the item/s of its reference at i, and returns the handle

If v is Assign (:) each item in the selection is replaced by the corresponding item in vy.

u and v can be replaced with values of higher rank using projection or by enlisting their arguments and using Apply.

See also binary and ternary forms of . and @
Apply, Apply At, Index, Index At

Examples

Amend Entire

If i is

  • the empty list (for .)
  • the general null (for @)

the selection is the entire value in d.

.[d;();u]     <=>   u[d]            @[d;::;u]     <=>   u'[d]      
.[d;();v;y]   <=>   v[d;y]          @[d;::;v;y]   <=>   v'[d;y]    
q).[1 2; (); 3 4 5]
4 5
q).[1 2; (); :; 3 4 5]
3 4 5
q).[1 2; (); ,; 3 4 5]
1 2 3 4 5
q)@[1 2; ::; ,; 3 4 5]
1 2 3 4 5

q)@[1 2; ::; *; 3 4]
3 8
q)@[1 2; ::; 3 4*]
'type
  [0]  @[1 2; ::; 3 4*]
       ^

Single path

If i is a non-negative integer vector then the selection is a single item at depth count i in d.

q)(5 2.14; "abc") . 1 2              / index at depth 2
"c"
q).[(5 2.14; "abc"); 1 2; :; "x"]    / replace at depth 2
5 2.14
"abx"

Cross sections

Where the items of i are non-negative integer vectors, they define a cross section. The result can be understood as a series of single-path amends.

q)d
(1 2 3;4 5 6 7)
(8 9;10;11 12)
(13 14;15 16 17 18;19 20)
q)i:(2 0; 0 1 0)
q)y:(100 200 300; 400 500 600)
q)r:.[d; i; ,; y]

Compare d and r:

q)d                              q)r
(1 2 3;4 5 6 7)                  (1 2 3 400 600;4 5 6 7 500)
(8 9;10;11 12)                   (8 9;10;11 12)
(13 14;15 16 17 18;19 20)        (13 14 100 300;15 16 17 18 200;19 20)

The shape of y is 2 3, the same shape as the cross-section selected by d . i. The (j;k)th item of y corresponds to the path (i[0;j];i[1;k]). The first single-path Amend is equivalent to:

d: .[d; (i . 0 0; i . 1 0); ,; y . 0 0]

(since the amends are being done individually, and the assignment serves to capture the individual results as we go), or:

d: .[d; 2 0; ,; 100]

and item d . 2 0 becomes 13 14,100, or 13 14 100. The next single-path Amend is:

d: .[d; (i . 0 0; i . 1 1); ,; y . 0 1]

or

d: .[d; 2 1; ,; 200]

and item d . 2 1 becomes 15 16 17 18 200.

Continuing in this manner:

  • item d . 2 0 becomes 13 14 100 300, modifying the previously modified value 13 14 100
  • item d . 0 0 becomes 1 2 3 400
  • item d . 0 1 becomes 4 5 6 7 500
  • item d . 0 0 becomes 1 2 3 400 600, modifying the previously modified value 1 2 3 400

Replacement

d:((1 2 3; 4 5 6 7)
   (8 9; 10; 11 12)
   (13 14; 15 16 17 18; 19 20))
i:(2 0; 0 1 0)
y:(100 200 300; 400 500 600)
r:.[d; i; :; y]

Compare d and r:

q)d                           q)r
(1 2 3;4 5 6 7)               600 500             / replaced twice; once
(8 9;10;11 12)                (8 9;10;11 12)
(13 14;15 16 17 18;19 20)     (300;200;19 20)     / replaced twice; once; not

Note multiple replacements of some items-at-depth in d, corresponding to the multiple updates in the earlier example.

Unary value

The ternary replaces the selection with the results of applying u to them.

q)d
(1 2 3;4 5 6 7)
(8 9;10;11 12)
(13 14;15 16 17 18;19 20)
q)i
2 0
0 1 0
q)y
100 200 300
400 500 600
q)r:.[d; i; neg]

Compare d and r:

q)d                            q)r
(1 2 3;4 5 6 7)                (1 2 3;-4 -5 -6 -7)
(8 9;10;11 12)                 (8 9;10;11 12)
(13 14;15 16 17 18;19 20)      (13 14;-15 -16 -17 -18;19 20)

Note multiple applications of neg to some items-at-depth in d, corresponding to the multiple updates in the first example.

On disk

Certain vectors can be updated directly on disk without the need to fully rewrite the file. (Since V3.4)

Such vectors must have no attribute, be of a mappable type, not nested, and not compressed.

q)`:data set til 20
q)@[`:data;3 6 8;:;100 200 300]
q)get `:data
0 1 2 100 4 5 200 7 300 9 10 11 12 13 14 15 16 17 18 19

Errors

domain   d is a symbol atom but not a handle
index    a path in i is not a valid path of d
length   i and y are not conformable
type     an atom of i is not an integer, symbol or nil
type     replacement items of different type than selection

Apply, Apply At, Index, Index At
Q for Mortals §6.8.3 General Form of Function Application