Overview
All data structures in q are ultimately built from lists: a dictionary is a pair of lists; a table is a special dictionary; a keyed table is a pair of tables. Thus it is important to have a thorough grounding in lists.
Introduction to Lists
List Definition and Assignment
q)(1; 1.1; `1)
1
1.1
`1
q)((1; 2; 3); (4; 5))
1 2 3
4 5
count
The number of items in a list is its count.
q)count (1; 2; 3)
3
q)first (1; 2; 3)
1
q)last (1; 2; 3)
3
Simple Lists
A list of atoms of a uniform type, called a simple list, corresponds to the mathematical notion of a vector.
Simple Integer Lists
q)100 200 300~(100; 200 ; 300)
1b
q)(1; 2; 3h)
1
2
3h
Simple Floating Point Lists
q)1.0 2.0 3.0
1 2 3f
q)1 2 3f~1.0 2.0 3.0
1b
Simple Binary Lists
q)(0b;1b;0b;1b;1b)
01011b
The 0x indicator for a simple list of byte precedes the list.
q)0x20a1ff~(0x20;0xa1;0xff)
1b
Simple Symbol Lists
q)(`Life;`the;`Universe;`and;`Everything)
`Life`the`Universe`and`Everything
Simple char Lists and Strings
q)("s"; "t"; "r"; "i"; "n"; "g")
"string"
A simple list of char is actually called a string; however, it does not have the atomic semantics of a string in most languages. Since it is a list of char, not an atom, you cannot ask if two strings of different lengths are equal. You can ask if they are identical (as you can with any two q entities).
q)"string"="text"
'length
q)"string"~"text"
0b
Lists of Temporal Data
q)(2000.01.01; 2001.01.01; 2002.01.01)
2000.01.01 2001.01.01 2002.01.01
q)(00:00:00.000; 00:00:01.000; 00:00:02.000)
00:00:00.000 00:00:01.000 00:00:02.000
Empty and Singleton Lists
The General Empty List
q)()
q)
q)L:()
q)L
q).Q.s1 L
"()"
If you want to force the display of an empty list, use the q utility .Q.s1, which converts any q entity into a string suitable for display.
Singleton Lists
Unfortunately, there is no way to type a singleton literal. Singletons are created by the function enlist, which “boxes” its argument into a list with one item. Note that it manages to avoid the usual q predilection for aggressively short names.
q)enlist 42
,42
A singleton need not contain an atom as its sole item; it can be any q entity.
q)enlist 1 2 3
1 2 3
q)enlist (10 20 30; `a`b`c)
10 20 30 a b c
Indexing
q)(100; 200; 300)[0]
100
q)100 200 300[0]
100
q)L:100 200 300
q)L[0]
100
q)L[3]
q)0N
Indexed Assignment
q)L:1 2 3
q)L[1]:42
q)L
1 42 3
Indexing Domain
q)L:(-10.0; 3.1415e; 1b; `abc; "z")
q)L[1.0]
'type
Empty Index and Null Item
An omitted index returns the entire list.
q)L:10 20 30 40
q)L[]
10 20 30 40
The syntactic form double-colon :: denotes the nil item, which allows explicit notation or programmatic generation of an empty index.
q)L[::]
::
q)L:(::; 1 ; 2 ; 3)
q)type L
0h
q).Q.s1 L[0]
"::"
This is one way to avoid a nasty surprise when q would otherwise automatically convert a list to simple type. A simple case is when you reassign the only non-conforming item in the list.
q)L:(1; 2; 3; `a)
q)L[3]:4
q)L
1 2 3 4
q)L[3]:`a
'type
After the reassignment you can no longer assign `a back into the list in its original position. One way to avoid this is by placing :: in the list as a guard.
q)L:(::; 1 ; 2 ; 3; `a)
q)L[4]:4
q)L[4]:`a
q)
Lists with Expressions
Any valid q expression can occur in list construction.
q)L1:1 2 3
q)L2:40 50
q)(L1; L2)
q)(count L1; sum L2)
q)3 90
Combining Lists
Joining with ,
q)1 2 3,4
1 2 3 4
Observe that if the arguments are not of uniform type, the result is a general list.
q)1 2 3,4.4 5.5
Merging with ^
Another way to combine two lists of the same length is by coalescing them with ^. The result is given by the rule that the right item prevails over the corresponding left item except when the right item is null.
q)L1:10 0N 30
q)L2:100 200 0N
q)L1^L2
100 200 30
Lists as Maps
A list not only acts like a map, it is a unary map whose notation is the same as function application.
Nesting
Data complexity is built by using lists as items of lists.
Depth
The number of levels of nesting for a list is called its depth. Informally, the depth measures how much repeated indexing is necessary to arrive at only atoms. Atoms have depth 0 and simple lists have depth 1. The notation of complex lists is reflected in nested parentheses.
q)L:(1;2;(100;200))
q)count L
3
q)L3:((1; 2h; 3j); ("a"; `bc`de); 1.23)
q)count L3
3
q)L3[1]
"a"
`bc`de
q)count L3[1]
2
q)m:((11; 12; 13; 14); (21; 22; 23; 24); (31; 32; 33; 34))
q)m[1][0]
q)21
Iterated Indexing and Indexing at Depth
Iterated Item Indexing
q)L:(1; (100; 200; (1000; 2000; 3000; 4000)))
q)L[1][2]
1000 2000 3000 4000
Indexing at Depth
There is an alternate notation for iterated indexing into a nested list. It is strictly syntactic sugar and amounts to the same thing under the covers. This notation is called indexing at depth and it looks exactly like application of a multi-valent function (which, in fact, it is). The previous retrieval can also be written as,
q)L[1;2;0]
1000
Assignment via index at depth works but assignment does not work with iterated indexing.
q)L:(1; (100; 200; (1000 2000 3000 4000)))
q)L[1; 2; 0]: 999
q)L
1
(100;200;999 2000 3000 4000)
q)L[1][2][0]:42
'assign
Indexing with Lists
Retrieving Multiple Items
By extension, we can retrieve a list of multiple items via multiple indices. For simplicity we use simple list notation for the indices.
q)L:100 200 300 400
q)L[0 2]
100 300
q)L[3 2 0 1]
q)400 300 100 200
q)"beeblebrox"[0 7 8]
"bro"
Indexing via a Variable
When retrieving items via multiple indices, the indices can live in a variable.
q)L
100 200 300 400
q)I:0 2
q)L[I]
100 300
Indexing with Nested Lists
We can retrieve via an arbitrary collection of indices. The retrieved list has the same shape as the index list.
q)L:100 200 300 400
q)L[(0 1; 2 3)]
100 200
300 400
Assignment with List Indexing
q)L[1 2 3]:2000 3000 4000
q)L
q)100 2000 3000 4000
Assignment via a simple index list is processed in sequence – i.e., from left-to-right.
q)L[3 2 1]:999 888 777
is equivalent to,
q)L[3]:999
q)L[2]:888
q)L[1]:777
You can assign a single value to multiple items in a list by using an atom for the assignment value.
q)L:100 200 300 400
q)L[1 3]:999
q)L
100 999 300 999
Juxtaposition
It is permissible to leave out the brackets and juxtapose the list and index with separating whitespace (usually just a blank).
q)L:100 200 300 400
q)L 2 1
300 200
q)L ::
100 200 300 400
Find (?)
The Find operator is (an overload of) binary ? that returns the index of the first occurrence of the right operand in the left operand.
q)1001 1002 1003?1002
1
If you try to find an item that is not in the list, the result is an integer equal to the count of the list.
q)1001 1002 1003?1004
3
Find is atomic in the right operand meaning that it extends to lists.
q)1001 1002 1003?1003 1001
2 0
作者:Jeffry A. Borror