Reputation:
I am Trying to create a function in Standard ML to create a string out of an int list [1,2,3,4]
such that it would look like "1, 2, 3, 4"
.
What I managed to create is a function that would do the job by iterating and converting to string and add ", ". But since i am concating the comma after each iteration, the comma would also end up at the end of the string.
Here is my function:
fun list_string lst =
(foldr (fn (x, y) => x ^ ", " ^ y ) "" (List.map (fn x => Int.toString(x)) lst));
You can see the problem that once it reaches the end, it will still print the comma. Is there a way i can add a function to the part with foldr so it can check the last element?
Upvotes: 1
Views: 644
Reputation: 3920
You can instead add a comma only if your not on the first item of your list. This can be simply checked by comparing y
to the empty string:
fun list_string lst = (List.foldr (fn (x, y) => if y = "" then x else x ^ "," ^ y)
"" (List.map (fn x => Int.toString(x)) lst));
print(list_string([1, 2, 3]));
You can also do it with pattern matching and without first mapping your int list into a string list. Hence you traverse your list only once. This is also more readable in my opinion:
fun list_string lst = List.foldr (
fn (x, "") => (Int.toString x)
| (x, y) => (Int.toString x) ^ "," ^ y) "" lst;
print(list_string([1, 2, 3]));
Upvotes: 1
Reputation: 16145
You could do this by folding:
fun commaSep [] = ""
| commaSep (n0::ns) =
foldl (fn (n, s) => s ^ ", " ^ Int.toString n)
(Int.toString n0)
ns
Or you could use concat
, map
and intersperse
:
fun intersperse x [] = []
| intersperse x [y] = [y]
| intersperse x (y::zs) = y :: x :: intersperse x zs
val commaSep = String.concat
o intersperse ", "
o List.map Int.toString
Upvotes: 0