Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Most idiomatic way to select elements from an array in Golang?

Tags:

arrays

slice

go

I have an array of strings, and I'd like to exclude values that start in foo_ OR are longer than 7 characters.

I can loop through each element, run the if statement, and add it to a slice along the way. But I was curious if there was an idiomatic or more golang-like way of accomplishing that.

Just for example, the same thing might be done in Ruby as

my_array.select! { |val| val !~ /^foo_/ && val.length <= 7 } 
like image 659
user2490003 Avatar asked Jun 01 '16 08:06

user2490003


People also ask

How do you search for an element in a Golang slice?

In the Go slice, you can search an element of string type in the given slice of strings with the help of SearchStrings() function. This function searches for the given element in a sorted slice of strings and returns the index of that element if present in the given slice.

How do I add a slice in Golang?

To add an element to a slice , you can use Golang's built-in append method. append adds elements from the end of the slice. The first parameter to the append method is a slice of type T . Any additional parameters are taken as the values to add to the given slice .

Does Go have a map function?

Map() Function in Golang is used to return a copy of the string given string with all its characters modified according to the mapping function.

How append works in Golang?

The append method in go allows you to add any number of specified items to the end of a slice. If the underlying array contains enough capacity, go use this array.


1 Answers

There is no one-liner as you have it in Ruby, but with a helper function you can make it almost as short.

Here's our helper function that loops over a slice, and selects and returns only the elements that meet a criteria captured by a function value:

func filter(ss []string, test func(string) bool) (ret []string) {     for _, s := range ss {         if test(s) {             ret = append(ret, s)         }     }     return } 

Using this helper function your task:

ss := []string{"foo_1", "asdf", "loooooooong", "nfoo_1", "foo_2"}  mytest := func(s string) bool { return !strings.HasPrefix(s, "foo_") && len(s) <= 7 } s2 := filter(ss, mytest)  fmt.Println(s2) 

Output (try it on the Go Playground):

[asdf nfoo_1] 

Note:

If it is expected that many elements will be selected, it might be profitable to allocate a "big" ret slice beforehand, and use simple assignment instead of the append(). And before returning, slice the ret to have a length equal to the number of selected elements.

Note #2:

In my example I chose a test() function which tells if an element is to be returned. So I had to invert your "exclusion" condition. Obviously you may write the helper function to expect a tester function which tells what to exclude (and not what to include).

like image 99
icza Avatar answered Sep 20 '22 14:09

icza