Karol Babioch
Karol Babioch

Reputation: 716

Split string and convert the substrings to integers in Go

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?

Upvotes: 9

Views: 9577

Answers (4)

Vinsensius Angelo
Vinsensius Angelo

Reputation: 1

try this solution (compatible with unlimited slice items) https://goplay.tools/snippet/cK025VBmRov

Upvotes: -1

icza
icza

Reputation: 417592

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

Making it strict

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.

Upvotes: 14

Eugene Lisitsky
Eugene Lisitsky

Reputation: 12845

Best option is to use maps:

V = make(map[int]int)

// in cycle
for i :=1; i < 3; i ++ {
    V[i], _ = strconv.AtoI(tmp[i])
}

Upvotes: 0

Adrian
Adrian

Reputation: 46432

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

Upvotes: 2

Related Questions