2016-10-19 2 views
-2

vielleicht ist es nicht nur ein Go-Problem, aber ich habe dieses Problem:Multiply 2 oder mehr Arrays in Golang

ich zwei multiplizieren will (oder mehr) Arrays, so zum Beispiel:

a := [3]int{2, 3, 5} 
b := [2]bool{true, false} 
// desired output of "c" => 
// [[2 true] [2 false] [3 true] [3 false] [5 true] [5 false]] 

Ich habe diese Bibliothek hier bereits gefunden: https://godoc.org/github.com/gonum/matrix/mat64 aber ich sehe nicht, wie man etwas anderes als float64

Die Fallback-Lösung wäre, mehrere For-Range-Loops zu verwenden, aber es wäre erstaunlich, wenn es ein " glatter "Weg, dies zu tun

Antwort

0

Kurze Antwort: go ist nicht für diese Art von Problem gedacht. Was Sie wollen, ist ein Äquivalent der zip Funktion, die nativ in einigen Sprachen vorhanden ist (zB Haskell, Python, ...)

In Golang haben Sie jedoch ein großes Problem: Sie können nicht dynamisch haben Arten. Das heißt: Ein Array kann nur einen Typ (int OR bool) enthalten, nicht mehrere. Die Problemumgehung besteht darin, ein Array von Schnittstellen zu erstellen, aber das bedeutet, dass Sie hässliche Typassertionen erstellen müssen, um den richtigen Typ zurück zu bekommen.

Auch Sie haben eine allgemeine Möglichkeit, das zu tun, aber der Typ, den Sie am Ende erhalten werden, ist und keine Möglichkeit zu wissen, was drin ist.

Für Ihr Beispiel: Hier ist die einfachste Art und Weise zu tun, was Sie (nicht allgemein) wollen:

func main() { 
    a := [3]int{2, 3, 5} 
    b := [2]bool{true, false} 
    var c [6][2]interface{} 
    i := 0 
    for _, val1 := range a { 
     for _, val2 := range b { 
      c[i] = [2]interface{}{val1, val2} 
      i += 1 
     } 
    } 

    var a1 int = c[0][0].(int) 
    var b1 bool = c[0][1].(bool) 
    fmt.Printf("c[0] is %v, a1 is %d and b1 is %v\n", c[0], a1, b1) 
    fmt.Println(c) 
} 

Wie Sie sehen können, das ist hässlich und nutzlos in der Praxis (und sehr fehleranfällig)

Also, wenn Sie diese Art von Transformationen machen möchten, sollten Sie eine andere Sprache verwenden, Go wurde (und wird nicht) für diese Art von Zwecken entwickelt.

+0

Vielen Dank @ t-claverie für Ihre Antwort. Ihr Code-Beispiel ist genau das, was ich mit "multiple For-Range-Schleifen" meinte ... aber die Sache ist, dass es noch mehr Arrays geben kann, die iteriert werden sollten ... Sie sagten, das größte Problem ist das "zwei Typen in einem Array" -Problem ... wie wäre es, diesen Teil meines Problems zu lösen, indem man das Array "c" durch eine Funktion "c" ersetzt, die die Typ-Awareness wie folgt hat: 'func c (a int , b bool) '? –

+0

@uzed_creative Wenn Sie den Typ und die Anzahl Ihrer Arrays haben, ist es möglich. Wenn Sie dies nicht tun, müssen Sie benutzerdefinierte Funktionen mit dem Typ 'func f (args interface {} ...)' erstellen, die die selbe Typ-Assertion wie oben ausführen. –

0

Dies ist keine Matrixmultiplikation, wie oben ausgeführt. Die zwei for-Schleifen funktionieren, wenn es nur zwei Dinge gibt, aber wenn es mehrere gibt, kann es deutlich mühsam werden.

Die Art, wie ich es tun würde, ist ein multidimensionales Array zu denken. Die Gesamt „Zahl“ von Elementen ist das Produkt der Größen und dann eine Funktion wie SubFor verwendet https://godoc.org/github.com/btracey/meshgrid#SubFor

dims := []int{3,2} 
sz := 1 
for _,v := range dims { 
    sz *= v 
} 
sub := make([]int, len(dims)) 
for i := 0: i < sz; i++{ 
    meshgrid.SubFor(sub, i, dims) 
    fmt.Println(a[sub[0]], b[sub[1]]) 
} 

Es gibt einige Dinge mit Typen, um herauszufinden, (zu einer Scheibe anhängt, etc.), aber das sollte dir den allgemeinen Kern geben.