I’d like to create a list such that input [(0 1),(0 1 2)] to
s0_0
s0_1
s0_2
s1_0
s1_1
s1_2
tried:
{[x,y] `$“s”,string x,string y}‘[til 2]’[til 3]
`$“s”, (string til 1),/::(string til 3)
I’d like to create a list such that input [(0 1),(0 1 2)] to
s0_0
s0_1
s0_2
s1_0
s1_1
s1_2
tried:
{[x,y] `$“s”,string x,string y}‘[til 2]’[til 3]
`$“s”, (string til 1),/::(string til 3)
Here’s one way
q){“C”$(z;;“_”;).'string x cross y}[til 2;til 3;“s”]
“s0_0”
“s0_1”
“s0_2”
“s1_0”
“s1_1”
“s1_2”
l:((0 1);(0 1 2));
l: string l;
raze {(“s”,x,“_”),/:(last l)} each (first l)
(Roundtrip: 000ms)
(“s0_0”;“s0_1”;“s0_2”;“s1_0”;“s1_1”;“s1_2”)
??, 14 ???. 2018 ?. ? 0:45, Sean O’Hagan <sohagan857@gmail.com>:
Here’s one way
q){“C”$(z;;“_”;).'string x cross y}[til 2;til 3;“s”]
“s0_0”
“s0_1”
“s0_2”
“s1_0”
“s1_1”
“s1_2”
because of left-of-right evaluation you’d need (string x),string y but the double ’ doesn’t work here - and you rarely need more than one.
/:: generates a matrix and in this case you want a list, you can raze it down to get a list:
q)(string til 2),/::(string til 3)
“00” “01” “02”
“10” “11” “12”
q)raze(string til 2),/::(string til 3)
“00”
“01”
“02”
“10”
“11”
“12”
string is atomic and you only need one in this case (and no need for the parens around til 3):
q)raze string(til 2),/::til 3
sv can join two strings:
q)"-"sv(“aa”;“bb”)
“aa-bb”
’ makes it work on a list of lists:
q)"_"sv’raze string(til 2),:/:til 3
and then stick an “s” in front of each:
q)“s”,'"_"sv’raze string(til 2),:/:til 3
cross is a little shorter:
q)“s”,'"_"sv’string(til 2)cross til 3
Sean’s solution uses a list map - a list with omitted elements behaves like a function - cool!
q)(1;;3;)[2;4]
1 2 3 4
You can use over or / to apply cross between the two lists.
q)`$“s”,'"_"sv’string(cross)over(0 1;0 1 2)
s0_0
s0_1s0_2
s1_0s1_1
s1_2
Since cross over will reduce more than two lists we can lose both the Join and the sv
q)`$raze each string(cross)over(“s”;0 1;“_”;0 1 2)
s0_0
s0_1s0_2
s1_0s1_1
s1_2
As Will points out, string is atomic. We can cast the lists to string, cross over them, and cast to symbol. As a lambda:
q){`$(cross/)string(“s”;x;“_”;y)}[0 1;0 1 2]
s0_0
s0_1s0_2
s1_0s1_1
s1_2
which perhaps reads something like a statement of the original problem.
Stephen Taylor | Librarian | Kx | +44 7713 400852 | stephen@kx.com
Here’s one more for good measure
f:{“s”,/:"_"sv/:string raze x,':y}
f[0 1;0 1 2]
“s0_0”
“s0_1”
“s0_2”
“s1_0”
“s1_1”
“s1_2”
Thanks everyone for the help!