Reputation: 31
Sorry for the trivial question. However I think I can figured out a couple of solutions but still not sure. I have the following table
t:flip `sym`exchange`bid`bsze!flip (
(`IBM;`A;100.9 100.8 100.7 100.8; 100 200 300 400);
(`FB;`A;100.4 100.3 100.2;100 200 300))
I want to extract the second element from the rows an assign it to a variable, I can do this using the following
[t`bid][;1]
However when I try to assign the value I get an error. For example
x:[t`bid][;1]
I get the following error
ERROR: 'y
(attempt to use variable y without defining/assigning first (or user-defined signal))
Also I can use
x:first each t`bid
But in this case how do I get the second level
Thank you for the help.
Upvotes: 1
Views: 1463
Reputation: 1097
Tables are indexed first by row, second by column. Eliding an index gets you all values for it.
q)t[1;`bid]
100.4 100.3 100.2
q)t[;`bid] / all rows
100.9 100.8 100.7 100.8
100.4 100.3 100.2
Table columns are always indexed as symbols; rows as integers. Confusion arises, because q exploits that difference to support a shorthand:
q)t[`bid] / i.e. t[;`bid]
100.9 100.8 100.7 100.8
100.4 100.3 100.2
q)t`bid / i.e. t[;`bid]
100.9 100.8 100.7 100.8
100.4 100.3 100.2
From this you can see the concise way to index the items you want is
q)a:t[;`bid;1] / all rows; bid column; 2nd item
q)a
100.8 100.3
Going beyond the OP, you might prefer a different scheme for t
. Clearly bid
and bsze
are to conform for each row. But nothing in the scheme ensures this. Tabulating them might protect them from corruption.
q)tb8:{flip x!y x}[`bid`bsze] / tabulate
q)show u:select sym,exchange,bids:tb8 each t from t
sym exchange bids
-----------------------------------------------------------------
IBM A +`bid`bsze!(100.9 100.8 100.7 100.8;100 200 300 400)
FB A +`bid`bsze!(100.4 100.3 100.2;100 200 300)
q)u[0;`bids]
bid bsze
----------
100.9 100
100.8 200
100.7 300
100.8 400
I have extended the Reference article on syntax to describe this:
https://code.kx.com/q/basics/syntax/#indexing-tables
Upvotes: 0
Reputation: 883
[t`bid][;1]
is technically not the correct syntax.
q)1+[t`bid][;1]
'type
[0] 1+[t`bid][;1]
^
q)1+t[`bid][;1]
101.8 101.3
When using square brackets, an expression is usually required on the left side. E.g. a function or variable. Square brackets will evaluate from the "immediate left" first - look at the example @Matthew provided, wheras circle brackets will force the evaluation within first. Right to left evaluation still applies but depending on the brackets used, it overwrites that behaviour.
https://code.kx.com/q/basics/syntax/#bracket-notation has some useful information on bracket notation.
In your case you mentioned you can use first each t`bid
- it is equivalent to {x 0}each t`bid
. To get the second element using the same method you can use {x 1}each t`bid
.
Some additional methods you can consider:
exec bid[;1] from t
Upvotes: 1
Reputation: 880
if i understand correctly, this should work
q)x:t[`bid][;1]
q)x
100.8 100.3
or equivalently
q)x:(t`bid)[;1]
q)x
100.8 100.3
Upvotes: 2