.
@
Amend, Amend At¶
Modify one or more items in a list, dictionary or datafile.
Amend Amend At values (d . i) or (d @ i)
.[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 datafilei
indexes whered
is to be amended:- it must be a list for
.
- if empty (for
.
) or the general null::
(for@
), or ifd
is a non-handle atom, the selection \(S\) isd
(Amend Entire) - otherwise \(S\) is
.[d;i]
or@[d;i]
- it must be a list for
u
is a unaryv
is a binary, andvy
is- in the right domain of
v
- unless \(S\) is
d
, conformable to \(S\) and of the same type
- in the right domain of
the items in d
of the selection \(S\) are replaced
- in the ternary, by
u[
\(S\)]
for.
and byu'[
\(S\)]
for@
- in the quaternary, by
v[
\(S\);vy]
for.
and byv'[
\(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]
3 8
q)@[(1 2;4 5); ::; ,; 3 6]
1 2 3
4 5 6
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"
Amend At¶
Indicies results are accumulated when repeated:
q)@[(0 1 2;1 2 3 4;7 8 9) ;1 1; 2*]
0 1 2
4 8 12 16 / equates to 2*2*1 2 3 4
7 8 9
q)@[(0 1 2;1 2 3 4;7 8 9) ;0 1 2 1; 100*]
0 100 200 / equates to 100*0 1 2
10000 20000 30000 40000 / equates to 100*100*1 2 3 4
700 800 900 / equates to 100*7 8 9
q)@[(0 1 2;1 2 3 4;7 8 9) ;0 1 2 1; {x*y};100]
0 100 200 / equates to {x*100}0 1 2
10000 20000 30000 40000 / equates to {x*100}{x*100}1 2 3 4
700 800 900 / equates to {x*100}7 8 9
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
becomes13 14 100 300
, modifying the previously modified value13 14 100
- item
d . 0 0
becomes1 2 3 400
- item
d . 0 1
becomes4 5 6 7 500
- item
d . 0 0
becomes1 2 3 400 600
, modifying the previously modified value1 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 (types 1-19) 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 be nested, enumerated, or 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
q)`:test set `:sym?9?`1
`:test
q)type get `:test
20h
q)@[`:test;0 1;:;`sym?`a`b]
'type/attr error amending file test
[0] @[`:test;0 1;:;`sym?`a`b]
^
On-disk amend to apply p
or g
attributes now avoids in-memory copying since 4.1t 2023.01.20.
q)`:tab/ set ([]where 10000#100);
q)@[`:tab/;`x;`p#]
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
type/attr error amending file test
Apply, Apply At, Index, Index At
Q for Mortals
§6.8.3 General Form of Function Application