Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove items from a slice while ranging over it?

Tags:

go

What is the best way to remove items from a slice while ranging over it?

For example:

type MultiDataPoint []*DataPoint  func (m MultiDataPoint) Json() ([]byte, error) {     for i, d := range m {         err := d.clean()         if ( err != nil ) {             //Remove the DP from m         }     }     return json.Marshal(m) } 
like image 838
Kyle Brandt Avatar asked Dec 12 '13 14:12

Kyle Brandt


People also ask

How do I remove an item from my slice?

To remove the first element, call remove(s, 0), to remove the second, call remove(s, 1), and so on and so forth. Hm, not really. This: s[i] = s[len(s)-1] definitely copies the last element to the element at index i . Then, return s[:len(s)-1] returns the slice without the last element.

How do you clear a slice in Golang?

Setting the slice to nil is the best way to clear a slice. nil slices in go are perfectly well behaved and setting the slice to nil will release the underlying memory to the garbage collector.

How do I append to a slice in Golang?

Since slices are dynamically-sized, you can append elements to a slice using Golang's built-in append method. The first parameter is the slice itself, while the next parameter(s) can be either one or more of the values to be appended.

How do you copy a slice in Golang?

To duplicate a slice in Go, getting a deep copy of its contents, you need to either use the built-in copy() function, or create a new empty slice and add all the elements of the first slice to it using the append() function.


1 Answers

As you have mentioned elsewhere, you can allocate new memory block and copy only valid elements to it. However, if you want to avoid the allocation, you can rewrite your slice in-place:

i := 0 // output index for _, x := range s {     if isValid(x) {         // copy and increment index         s[i] = x         i++     } } // Prevent memory leak by erasing truncated values  // (not needed if values don't contain pointers, directly or indirectly) for j := i; j < len(s); j++ {     s[j] = nil } s = s[:i] 

Full example: http://play.golang.org/p/FNDFswPeDJ

Note this will leave old values after index i in the underlying array, so this will leak memory until the slice itself is garbage collected, if values are or contain pointers. You can solve this by setting all values to nil or the zero value from i until the end of the slice before truncating it.

like image 142
tomasz Avatar answered Sep 23 '22 06:09

tomasz