How do I parse a ctrl-A delimited string?
Short answer: “\001” vs data
Use the vs (vector from scalar) function:
q)fstring
“f1=va\001f2=vb\001f3=vc”
q)”\001″ vs fstring
“f1=va”
“f2=vb”
“f3=vc”
q)
We can combine vs with /: (each right) to break up each component:
q)”=” vs/: “\001” vs fstring
“f1” “va”
“f2” “vb”
“f3” “vc”
q)
Note that you cannot put any space between vs and /:. If you did, that would be a comment.
We might next turn fstring’s contents into a table using a combination of flip and ! (dict):
q)flip "=" vs/: "\001" vs fstring
"f1" "f2" "f3"
"va" "vb" "vc"
q)`field`value ! flip "=" vs/: "\001" vs fstring
field| "f1" "f2" "f3"
value| "va" "vb" "vc"
q)flip `field`value ! flip "=" vs/: "\001" vs fstring
field value
-----------
"f1" "va"
"f2" "vb"
"f3" "vc"
q)
This is almost what we want. Usually, though, you want the field names to be symbols rather than strings. We can do that by applying (@) the $ (cast) operator to (only) the values of the field column:
q)columns: @[flip "=" vs/: "\001" vs fstring; 0; `$]
q)columns
f1 f2 f3
"va" "vb" "vc"
q)flip `field`value ! columns
field value
-----------
f1 "va"
f2 "vb"
f3 "vc"
q)
However, there is a shortcut we can take to deconstruct the string into a table using one of the many variants of 0::
q)flip `field`value ! “S=\001” 0: fstring
field value
———–
f1 “va”
f2 “vb”
f3 “vc”
q)
Not only is this last example more succinct, it’s much faster:
q)\t do[100000;
flip `field`value !
@[flip "=" vs/: "\001" vs fstring; 0; `$]]
485
q)\t do[100000; flip `field`value ! "S=\001" 0: fstring]
110
q)