If you want to split the list into lists of equal size, see this related faq on the # (take) operator.

If you want to split a string on a delimiter, use the vs (vector from scalar) function:

q)” ” vs “The quick brown fox”
“The”
“quick”
“brown”
“fox”
q)”, ” vs “Hello, world!”
“Hello”
“world!”
q)

When its left argument is the null symbol, `, the vs function breaks apart a symbol on dots:

q)` vs `foo.bar.baz
`foo`bar`baz
q)

Those are the most common cases. We can also split a list into lists of varying length by passing a list of indexes as the left argument to the _ (cut) operator:

q)0 1 4 9 _ til 10
,0
1 2 3
4 5 6 7 8
,9
q)

To split a list of some type other than char using a delimiter is a little more complicated. We start by finding the indexes in the list that match the delimiter:

q)list: 1 2 0 3 4 0 5 6
q)delimiter: 0
q)indexes: where delimiter = list
q)indexes
2 5
q)

Now we can break list into pieces using the _ (cut) operator as above:

q)indexes _ list
0 3 4
0 5 6
q)

This is almost what we want. We’ll use _/: (drop-each-right) to get rid of the delimiters:

q)1 _/: indexes _ list
3 4
5 6
q)

We can grab the first element of the result with # (take):

q)first[indexes] # list
1 2
q)

Then we can just join (using ,) the two together:

q)(enlist first[indexes] # list), 1 _/: indexes _ list
1 2
3 4
5 6
q)

Note that we must call enlist on the front of the list or else we’ll get something a little different from what we intended:

q)(first[indexes] # list), 1 _/: indexes _ list
1
2
3 4
5 6
q)

Lastly, we can generalize to non-atomic types by replacing = with ~/: (match-each-right):

split: {[list; delimiter]
indexes: where delimiter ~/: list;
front: first[indexes] # list;
rest: 1 _/: indexes _ list;
: (enlist front), rest;
}

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)

See also How do I build a ctrl-A delimited string?