I'm trying to parse log strings, where fields are glued with "|" char. All logs suppose to have 20 fields, but some logs have less. I don't want to discard them, but rather fill Log{}
with whatever info was there in the log string.
type Log struct {
Field1 string
Field2 uint64
Field3 string
// ...
Field20 string
}
Knowing that it's not possible to check if index exists within a slice, this looks suboptimal:
log := Log{}
c := len(fields)
if c > 0 {
log.Field1 = fields[0]
}
if c > 1 {
log.Field2, _ = strconv.ParseUint(fields[1], 0, 64)
}
if c > 3 {
log.Field3 = fields[2]
}
//...
Any better ways doing this?
Thanks
One possibility would be to simply ensure that you always have 20 elements in your slice. Assuming you're populating fields
with strings.Split
, for example:
fields := make([]string, 20)
copy(fields, strings.Split(input, ","))
// Now `fields` has 20 elements, the first N of which are populated
// by your input, the remainder of which are empty strings (""), so
// you can easily set your struct fields now.
log := Log{
Field1: fields[0],
Field2: fields[1],
// ...
Field20: fields[19],
}
One option is to use switch with fallthrough:
switch len(fields) {
case 20:
log.Field20 = something(fields[19])
fallthrough
// ...
case 3:
log.Field3 = fields[2]
fallthrough
case 2:
log.Field2, _ = strconv.ParseUint(fields[1], 0, 64)
fallthrough
case 1:
log.Field1 = fields[0]
}
playground example (thank you @mkopriva for starting example)