Problem description:
I've a slice bar
. I want to create another slice foo
with the first two elements of bar if there're at least 2 elements in bar
. Or with the first element of bar
if bar
has at least one element.
The idea I had:
// bar := []int{1, 2, 3...
foo := bar[:(int)(math.Min(float64(len(bar)), 2))]
EDIT: Here's another way I tried,
x := 2
if len(bar) < 2 {
x = len(bar)
}
foo := bar[:x]
Is it possible to improve the code? At least, casting twice to achieve something so simple doesn't look good to me.
If the length of your slice is greater than 2, you can reslice it. If not, no need to reslice just use the slice itself in assignment which will automatically satisfy your needs: result will have up to a maximum of 2 elements.
You can even "spare" the else
branch of the if
:
foo := bar
if len(foo) > 2 {
foo = foo[:2]
}
Note:
Slices are reference types. So even though you used bar
to initialize foo
, if you modify the foo
variable afterwards (not the elements of the slice), that does not affect bar
(the reference value is copied when assigned):
bar := []int{0, 1, 2, 3}
foo := bar
if len(foo) > 2 {
foo = foo[:2]
}
fmt.Println(foo) // Here foo is [0, 1] as expected
foo = foo[:1] // Reslicing foo
fmt.Println(bar) // Bar is unaffected, bar = [0 1 2 3]
Output (try it on the Go Playground):
[0 1]
[0 1 2 3]
Just use an if
. It's much more readable and performant, since there is no conversion between int
and float64
.
var foo []int
if len(bar) > 1 {
foo = bar[:2]
} else {
foo = bar[:len(bar)]
}
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