Hi All,
I'm trying to create a function to split a string by a tag - </OFX>. However, when trying return a seq[String], I'm getting an empty seq. I'm new to Nim, having primarily worked with PHP.
A couple of questions:
1. When trying to compile without {.Discardable.} I get an error - van2.nim(49, 24) Error: expression 'splitstring(new_string, split_by, accu)' is of type 'seq[string ]' and has to be discarded; start of expression here: van2.nim(39, 8)
Thank you all!
program:
import strutils
import typeinfo
import sequtils
let file:string = readfile("testing")
proc splitstring(string_to_split: string, split_by: string, acc: seq[string]): seq[string] {.discardable.} =
let search_len: int = split_by.len
let found: int = string_to_split.find(split_by)
let end_position: int = found + search_len + -1
echo(end_position)
if found != -1:
echo("string was found")
let new_string_start: int = end_position + 1
let new_string: string = string_to_split[new_string_start..^1]
if len(acc) == 0:
var accu: seq[string]
accu.add(string_to_split[0..end_position])
splitstring(new_string,split_by,accu)
else:
var accu: seq[string] = acc
accu.add(string_to_split[0..end_position])
splitstring(new_string,split_by,accu)
else:
echo(acc)
let result = acc
return result
#start of main
var indi_files = splitstring(file,"</OFX>",@[])
echo(indi_files)
echo(indi_files)
output: 17 string was found 25 string was found 4 @["asdfasdfasdf</OFX>", "bbbbbbbbbbbbbbbbbbbb</OFX>"] @[] @[] ::
seq have value semantics, meaning they are copied.
You have 2 issues:
Thank you very Mratsim! That worked. It seems like the function is returning too early - I'm assuming because result is being used in the if block? I modified the proc to make it a bit more obvious what is happening, and when. I'm expecting two values in the seq to be returned not one. A second question that I have is, I'm expecting that when proc is being called in that first if block - both with the if, and else that the rest of the proc is being foregone. Am I thinking about this the right way?
import sequtils
let file = readfile("testing")
proc splitstring(string_to_split: string, split_by: string, acc: seq[string]): seq[string] {.discardable.} =
let search_len = split_by.len
let found = string_to_split.find(split_by)
let end_position = found + search_len + -1
echo(end_position)
if found != -1:
echo("string was found")
let new_string_start = end_position + 1
let new_string = string_to_split[new_string_start..^1]
if len(acc) == 0:
result.add(string_to_split[0..end_position])
splitstring(new_string, split_by, result)
else:
result = acc
result.add(string_to_split[0..end_position])
splitstring(new_string,split_by, result)
else:
echo("the final result of splitting was ",acc)
result = acc
#start of main
var indi_files = splitstring(file,"</OFX>",@[])
echo("the final result returned to indi_files ",indi_files)
Output
17 string was found 25 string was found 4 the final result of splitting was @["asdfasdfasdf</OFX>", "bbbbbbbbbbbbbbbbbbbb< /OFX>"] the final result returned to indi_files @["asdfasdfasdf</OFX>"]
Remove {.discardable.}. Don't use that pragma if you don't understand how Nim works.
When trying to compile without {.Discardable.} I get an error - van2.nim(49, 24) Error: expression 'splitstring(new_string, split_by, accu)' is of type 'seq[string ]' and has to be discarded; start of expression here: van2.nim(39, 8)
Return values of a function can't be implicitly ignored in Nim without {.discardable.}
How do I return a copy of the resulting sequence of string?
Nim's sequences use value semantics, so they are always copied, for example (run on playground):
var
a = @[1, 2, 3, 4]
b = a
b.add 5
echo a # @[1, 2, 3, 4]
echo b # @[1, 2, 3, 4, 5]
It seems like the function is returning too early - I'm assuming because result is being used in the if block?
The function is not returning too early. The problem is that you dropped the return value of your recursion calls (which you didn't notice thanks to {.discardable.}), so they disappeared.
It's worth noting that result is just like any ordinary variable and will not cause any control-flow changes.
Here's my simplification of the function you presented: https://play.nim-lang.org/#ix=1P25. But please just use strutils.split instead.