Reputation: 4218
I append an unknown number of items (arround 10.000) into a slice
le := 500
l := make([]string, le)
l = append(l, "a")
l = append(l, "b")
l = append(l, "c")
l = append(l, "d")
l = append(l, "...")
for i, v := range l{
fmt.Printf("i:%d-v:%s\n", i, v)
}
After this my slide contains
i:0-v:
...
i:500-v:a
i:501-v:b
i:502-v:c
i:503-v:d
i:504-v:e
I'm looking for a way to get only the initialized items stored in the slice.
I want to be rid of i:0-v:
to i:499-v:
I can get the desired result re-slicing l
, to remove the first elements of the slice (the number of first elements dépends on the length
parameter passed to the make
method).
l = l[le:]
for j, k := range l{
fmt.Printf("i:%d-v:%s\n", j, k)
}
My question is: Is it the right way to achieve this or is there a nicer way to get rid of the items not initialized, added during the append?
Upvotes: 1
Views: 275
Reputation: 417542
You may create a slice using 0 length and capacity provided, the builtin make()
function takes an optional 3rd parameter being the capacity:
l := make([]string, 0, 1000) // Use a capacity that is enough for you
This way you can append elements without append()
having to reallocate (and implicitly copy) the contents if the current capacity is not enough to perform the append.
Also note that it is more efficient to set elements using indexing than appending (by using append()
you have to assign the returned slice header back even though most of the time it doesn't change):
c, l := 0, make([]string, 1000) // Use a length that is enough for you
l[c], c = "a", c+1
l[c], c = "b", c+1
l[c], c = "c", c+1
l[c], c = "d", c+1
l[c], c = "e", c+1
// We're done: slice the slice:
l = l[:c]
for i, v := range l {
fmt.Printf("i:%d-v:%s\n", i, v)
}
Output (try it on the Go Playground):
i:0-v:a
i:1-v:b
i:2-v:c
i:3-v:d
i:4-v:e
Also note that in practice when you fill your slice with values you receive from somewhere, the manual counter handling is not needed, a loop takes care of that. For example:
c := 0
for ; c < 5; c++ {
l[c] = string('a' + c) // Acquire next element to store in the slice
}
// We're done: slice the slice:
l = l[:c]
Try this one on the Go Playground.
Note that you can only use this though if you create a slice that you're sure won't be small, else l[c]
would give you a runtime panic when c
reaches the length.
Upvotes: 3
Reputation: 26667
Why not make an empty slice,
// create a slice with len 0
l := []string{}
l = append(l, "a")
l = append(l, "b")
l = append(l, "c")
l = append(l, "d")
l = append(l, "...")
will give an output,
i:0-v:a
i:1-v:b
i:2-v:c
i:3-v:d
i:4-v:...
Upvotes: 3