2017-12-13 16 views
-2

Go言語を学習し始めたばかりで、スライスからランダムなサブシーケンスを選択する関数を作成したいと考えています。しかし、私はこのスライスにどのようなタイプの値を格納できるか分かりません。これらは整数、文字列、またはいくつかの構造体の要素です。たとえば、のは、私が構造を持っていると仮定してみましょう:入力スライス引数に応じて異なる操作を実行する関数を作成する

type person struct { 
    name string 
    age int 
} 

type animal struct { 
    name string 
    age int 
    breed string 
} 

は今、私は次のように機能getRandomSequenceを構築したい:スライスSと機能がよりリットルランダムに選択された要素が含まれているスライスを返す長さl引数として与えられました私が遭遇した問題は、 - 可能なスライスに対してこの機能を動作させる方法でした。私は以下をしようとしました:

func GetRandomSequence(S interface{}, l int) []interface{} { 
    switch S.(type) { 
    case person: 
     // Do random selection of l elements from S and return them 
    case animal: 
     // Do random selection of l elements from S and return them 
    case int: 
    // Do random selection of l elements from S and return them 
    } 
    return " Not Recognised" 
} 

私はそのような機能をどのように書くことができますか? Sがどんなタイプの単一要素であっても(つまり、[]interface{}の代わりにちょうどinterface{}になる)類似の(つまり、一般的な)関数を動作させることができますが、この問題の解決方法を見つけることはできません。

+1

質問の本文が意味するように異なるスライスタイプで同じ操作を実行する方法を尋ねられていますか、タイトルに何が書かれているかを尋ねていますか? –

+1

あなたが新しくなれば、最高の助言は言語と戦わずにそのような機能を書くことではなく、 2つまたは3つ。 – Volker

答えて

1

interface{}ではなく、[]interface{}を使用してください。空のインターフェイスには、スライスを含むあらゆるタイプを格納できます。 (私がテストしていないが)

あなたのコードは次のようになります。

func GetRandomSequence(S interface{}, l int) interface{} { 
    returnSlice := []interface{} 
    switch v := s.(type) { 
    // inside the switch v has the value of S converted to the type 
    case []person: 
     // v is a slice of persons here 
    case []animal: 
     // v is a slice of animals here 
    case []int: 
     // v is a slice of ints here 
    case default: 
     // v is of type interface{} because i didn't match any type on the switch 
     // I recommend you return nil on error instead of a string 
     // or always return 2 things, the value and an error like 
     // the standard library 
     return "Not Recognized" 
    } 
    rerurn returnSlice 
} 

私はあなたが完全Tour of goを行うが、この質問に対しての答えはhereあるお勧めします。

正確に何をしたいかによって、スライスのタイプは異なりますが、スライスはinterface{}のように見えます。スライスからランダムな要素を抽出するためにあなたの機能であなたは、要素の種類を気にしない場合は、単に実行します。

func GetRandomSequence(S []interface{}, l int) []interface{} { 
    returnSlice := make([]interface{}, 0, l) 
    for i:=0; i<l; i++ { 
     // S[i] here is always of type interface{} 
     returnSlice = append(returnSlice, S[getRnd()]) // you need to implement getRnd() or just "math/rand" or something. 
    } 
    return returnSlice 
} 
1

は、スライスインデックスで動作サンプル関数を記述します。

// Sample k random elements from set of n elements. 
// The function set sets an element in the output given 
// an index in the output and the index in the input. 
func sample(k int, n int, assign func(out int, in int)) { 
    for i := 0; i < k; i++ { 
     set(i, i) 
    } 
    for i := k; i < n; i++ { 
     j := rand.Intn(i + 1) 
     if j < k { 
      set(j, i) 
     } 
    } 
} 

このようにそれを使用してください:sample長さの作品とインデックス値が唯一、それがどのようなタイプのスライスに使用することができますので

in := []person{ {"John", 10}, {"Sally", 11}, {"James", 9}, {"Eve", 8} } 
out := make([]person, 2) 
sample(len(out), len(in), func(i, j int) { out[i] = in[j] }) 

このアプローチは、標準ライブラリのsort.Searchに似ています。

+0

巧妙な回避 –

関連する問題