I've got a single variable containing something like 1,2,3
. These are actually three values, that I want to have in three variables called v1
, v2
, v3
(but not in an array).
Right now I'm doing this in the following way:
tmp := strings.Split(*w, ",")
sw, _ := strconv.Atoi(tmp[0])
rw, _ := strconv.Atoi(tmp[1])
pw, _ := strconv.Atoi(tmp[2])
This works, although it is very repetitive and does not feel right in Go.
What would be a cleaner way to solve this issue?
Use the Split method when the substrings you want are separated by a known delimiting character (or characters). Regular expressions are useful when the string conforms to a fixed pattern. Use the IndexOf and Substring methods in conjunction when you don't want to extract all of the substrings in a string.
The Split() method in Golang (defined in the strings library) breaks a string down into a list of substrings using a specified separator. The method returns the substrings in the form of a slice.
The split() method splits a string into an array of substrings. The split() method returns the new array. The split() method does not change the original string. If (" ") is used as separator, the string is split between words.
Parsing data out of a string
with a specific format and storing the parsed values into variables is a perfect task for and is easily done using fmt.Sscanf()
:
src := "1,2,3"
var a, b, c int
parsed, err := fmt.Sscanf(src, "%d,%d,%d", &a, &b, &c)
fmt.Println(parsed, err, a, b, c)
Output (try it on the Go Playground):
3 <nil> 1 2 3
As noted, this is very lenient, and will also successfully parse the "1,2,3,"
and "1,2,3,4"
inputs. This may or may not be a problem (depending on your case). If you want to make it strict, you can apply this little trick:
var temp int
parsed, err := fmt.Sscanf(src+",1", "%d,%d,%d,%d", &a, &b, &c, &temp)
What we do is we append one more of the numbers that matches the input. If the original input does not end with a number (such as "1,2,3,"
), parsing will fail with a non-nil
error, and the above example gives:
3 expected integer 1 2 3
Try it on the Go Playground. Of course it will continue to parse "valid" inputs without any errors.
Note that this still accepts the input "1,2,3,4"
. We can "reduce" this trick to a single character, and we don't necessarily need a "target" variable to store it, it may simply be designated by the format string, like in this example:
parsed, err := fmt.Sscanf(src+"~", "%d,%d,%d~", &a, &b, &c)
We append a special character unlikely to happen in the input, and we expect that special character in the format string. Attempting to parse an invalid input (such as "1,2,3,"
or "1,2,3,4"
) will result in an error such as:
3 input does not match format 1 2 3
Try it on the Go Playground.
If you're fine with a slice result, you could do it with slices:
tmp := strings.Split(*w, ",")
values := make([]int, 0, len(tmp))
for _, raw := range tmp {
v, err := strconv.Atoi(raw)
if err != nil {
log.Print(err)
continue
}
values = append(values, v)
}
Working playground example: https://play.golang.org/p/Y-QHmHP8Iy
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With