根据Go中的条件从切片中选择值的最惯用的方法是什么?

时间:2014-11-30 01:36:30

标签: go slice

我已经做了很多循环来过滤值,有时甚至将切片转换为带有方便索引的地图来实现这一点,但我觉得这可能不是Go中最好的方法。所以:

考虑以下样板代码,找到第一个名为" Bob"的第一个人,最常用的方法是什么?在people切片? found应该是一个bool变量来确定一个名为" Bob"被发现与否。

package main

import "fmt"

type Person struct {
    Age int
    Name string
}

var people=[]Person{{Age:18,Name:"Deb"},{Age:22,Name:"Bob"},{Age:35,Name:"Bob"}}

func main() {
    FirstBob, found := // how to pick first "Bob"?
    fmt.Println(FirstBob)
}

更一般:从匹配特定条件的切片中挑选第一个值的最常用方法是什么?

2 个答案:

答案 0 :(得分:2)

例如,

package main

import "fmt"

type Person struct {
    Age  int
    Name string
}

var people = []Person{{Age: 18, Name: "Deb"}, {Age: 22, Name: "Bob"}, {Age: 35, Name: "Bob"}}

func findPerson(people []Person, name string) (Person, bool) {
    for _, p := range people {
        if p.Name == name {
            return p, true
        }
    }
    return Person{}, false
}

func main() {
    FirstBob, found := findPerson(people, "Bob")
    if found {
        fmt.Println(FirstBob)
    }
}

输出:

{22 Bob}

如果要返回指向Person结构的指针,

package main

import "fmt"

type Person struct {
    Age  int
    Name string
}

var people = []Person{{Age: 18, Name: "Deb"}, {Age: 22, Name: "Bob"}, {Age: 35, Name: "Bob"}}

func findPerson(people []Person, name string) (*Person, bool) {
    for i := range people {
        p := &people[i]
        if p.Name == name {
            return p, true
        }
    }
    return nil, false
}

func main() {
    FirstBob, found := findPerson(people, "Bob")
    if found {
        fmt.Println(*FirstBob)
    }
}

输出:

{22 Bob}

答案 1 :(得分:2)

惯用的方法是写出循环 - 例如,Go团队成员(以及前Python编码员)Andrew Gerrand在GopherCon 2014的闭幕演讲中提到了其他功能样式列表处理快捷方式(“过滤器”,“地图”) ,等等)https://www.youtube.com/watch?v=dKGmK_Z1Zl0&t=23m40s

标准的理由是,不使用这些快捷方式会产生更一致的代码(开发人员无法对是否使用map做出不同的选择),并且它是明确的(当你'时它会更明显)如果循环作为for块可见,则在大型数据集上执行嵌套循环或循环。

那就是说,1)如果你重复相同类型的搜索很多地方你可能会像在peterSO的答案中那样考虑因素,2)“惯用语”是一个不是所有代码的理想选择一直满足;如果您认为它使您的代码更容易使用,那么没有什么能阻止您编写特定于类型的快捷方式(请注意:type People []Person; func (p People) FirstMatchingIndex(predicate func(p *Person) bool) int {...})。例如,标准strings.IndexFunc接近于“满足谓词的第一项的查找(索引)”。