2014-11-16 10 views

risposta

10

Si potrebbe fare qualcosa di simile this, in cui si dà un nome del tipo di parametri:

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)) 
} 

Oppure, in alternativa utilizzare un tipo senza nome per la tupla, come 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)) 
} 

E infine here's un modo soft-generico di farlo:

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) 
} 
4

Per zip un determinato numero di fetta []int liste,

package main 

import "fmt" 

func zip(lists ...[]int) func() []int { 
    zip := make([]int, len(lists)) 
    i := 0 
    return func() []int { 
     for j := range lists { 
      if i >= len(lists[j]) { 
       return nil 
      } 
      zip[j] = lists[j][i] 
     } 
     i++ 
     return zip 
    } 
} 

func main() { 
    a := []int{1, 2, 3} 
    b := []int{4, 5, 6} 
    c := []int{7, 8, 9, 0} 
    iter := zip(a, b, c) 
    for tuple := iter(); tuple != nil; tuple = iter() { 
     fmt.Println("tuple:", tuple) 
    } 
} 

uscita:

 
tuple: [1 4 7] 
tuple: [2 5 8] 
tuple: [3 6 9] 
Problemi correlati