Given a string S of white space separated words containing two words at least,
in Python I can say
x,y,*rest= S.split()
where rest is a tuple of remaining words if S contained more than 2 words.
Is there something similar in Nim?
Many thanks for a hint, Helmut
There isn't a way of doing this in Nim. However, you can (sort of) work around this:
let
s = x.splitWhitespace()
(x, y, rest) = (s[0], s[1], s[2..^1])
You can build some syntactic sugar ..= that allows to unpack sequences and arrays (implementation in this SO answer). With that you can do (taking also advantage of maxsplit parameter):
var a, b, rest: string
(a, b, rest) ..= "a b rest of the alphabet...".split(maxsplit=2)
echo a, b # ab
echo rest # rest of the alphabet...
# in case you are not gonna use the rest
(a, b) ..= "a b rest of the alphabet...".split(maxsplit=2)
echo a, b # ab
Note that rest is a string and not a seq[string]. You can adapt the syntactic sugar above (here I call it ...= with 3 dots) and have:
var restAsSeq: seq[string]
(a, b, restAsSeq) ...= "a b rest of the alphabet...".split() # this does return tail of string and discards it
echo a, b
echo restAsSeq # @["rest", "of", "the", "alphabet..."]
In case you do not need to use the rest, note that split proc does still allocate and return the rest of the string and it is the macro that throws away the stuff not needed (in particular the above would work the same without maxsplit).
A more efficient solution in case you have a very long string and you want to avoid even the allocation could be:
proc first(s: string, n: int): seq[string] =
var i = 0
for e in split(s): # this uses split iterator and only parses what it needs
result.add e
inc i
if i >= n:
break
(a, b) ..= "a b c d e f".first(2)
echo a, b
The discussion moved towards discussion split and performance which is not related to the question - the tuple/sequence unpacking - which is very handy and useful.
It could be also done that way https://stackoverflow.com/a/63802982/231624
macro first[T](s:openArray[T],l:static[int]):untyped =
result = newNimNode(nnkPar)
for i in 0..<l:
result.add nnkBracketExpr.newTree(s,newLit(i))
let (a,b) = "a/b/c".split('/').first(2)
Although I personally would like Nim to provide native support unpacking tuples/sequences/named-tuples/objects, both positional and key-based.