go - Go中如何将 slice 组合成一个元组 slice (实现python `zip`函数)?

标签 go slice zipper python-zip

有时,使用 Python 中的 zip 内置函数将两个列表组合成一个元组很方便。如何在 Go 中进行类似的操作?

例如:

>>> zip ([1,2],[3,4])
[(1,3), (2,4)]

最佳答案

您可以执行 this 之类的操作,在这里你给元组类型一个名字:

package main

import "fmt"

type intTuple struct {
    a, b int
}

func zip(a, b []int) ([]intTuple, error) {

    if len(a) != len(b) {
        return nil, fmt.Errorf("zip: arguments must be of same length")
    }

    r := make([]intTuple, len(a), len(a))

    for i, e := range a {
        r[i] = intTuple{e, b[i]}
    }

    return r, nil
}

func main() {
    a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
    b := []int{0, 9, 8, 7, 6, 5, 4, 3, 2, 1}
    fmt.Println(zip(a, b))
}

或者对元组使用未命名的类型,例如 this :

package main

import "fmt"

func zip(a, b []int) ([][3]int, error) {

    if len(a) != len(b) {
        return nil, fmt.Errorf("zip: arguments must be of same length")
    }

    r := make([][4]int, len(a), len(a))

    for i, e := range a {
        r[i] = [2]int{e, b[i]}
    }

    return r, nil
}

func main() {
    a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
    b := []int{0, 9, 8, 7, 6, 5, 4, 3, 2, 1}
    fmt.Println(zip(a, b))
}

最后是 here's一种软通用的方法:

package main

import (
    "fmt"
    "reflect"
)

func zip(a, b, c interface{}) error {

    ta, tb, tc := reflect.TypeOf(a), reflect.TypeOf(b), reflect.TypeOf(c)

    if ta.Kind() != reflect.Slice || tb.Kind() != reflect.Slice || ta != tb {
        return fmt.Errorf("zip: first two arguments must be slices of the same type")
    }

    if tc.Kind() != reflect.Ptr {
        return fmt.Errorf("zip: third argument must be pointer to slice")
    }

    for tc.Kind() == reflect.Ptr {
        tc = tc.Elem()
    }

    if tc.Kind() != reflect.Slice {
        return fmt.Errorf("zip: third argument must be pointer to slice")
    }

    eta, _, etc := ta.Elem(), tb.Elem(), tc.Elem()

    if etc.Kind() != reflect.Array || etc.Len() != 2 {
        return fmt.Errorf("zip: third argument's elements must be an array of length 2")
    }

    if etc.Elem() != eta {
        return fmt.Errorf("zip: third argument's elements must be an array of elements of the same type that the first two arguments are slices of")
    }

    va, vb, vc := reflect.ValueOf(a), reflect.ValueOf(b), reflect.ValueOf(c)

    for vc.Kind() == reflect.Ptr {
        vc = vc.Elem()
    }

    if va.Len() != vb.Len() {
        return fmt.Errorf("zip: first two arguments must have same length")
    }

    for i := 0; i < va.Len(); i++ {
        ea, eb := va.Index(i), vb.Index(i)
        tt := reflect.New(etc).Elem()
        tt.Index(0).Set(ea)
        tt.Index(1).Set(eb)
        vc.Set(reflect.Append(vc, tt))
    }

    return nil
}

func main() {

    a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
    b := []int{0, 9, 8, 7, 6, 5, 4, 3, 2, 1}
    c := [][2]int{}

    e := zip(a, b, &c)

    if e != nil {
        fmt.Println(e)
        return
    }

    fmt.Println(c)
}

关于go - Go中如何将 slice 组合成一个元组 slice (实现python `zip`函数)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26957040/

相关文章:

go - Bcrypt hashedSecret 太短,不能成为 bcrypted 密码

python - 有没有更聪明的方法来获取用切片对象切片的列表的索引?

python - 使用具有多种数据类型的索引列表对 Pandas 系列对象进行切片

haskell - 共同寻找所有关注网格的方法

haskell - Haskell 中存在类型的类型错误

go - 如何使用 go-git 查找 sha of origin/master?

xml - 一个简单的 xml 元素如何解码为 golang 结构?

c - C 中的字符串切片和复制

serialization - 序列化 zipper ?

mongodb - Golang BSON 转换