Pippi Life

主に仕事に関連するITのことや、プライベートもちょいちょい書きます。

golangで配列を、分散してマージしたい

タイトルのとおり、なのですが、 コードを書いていて、以下みたいなマージをしたかったので、メモしておきます。

func main() {
    s1 := []int{1, 2, 3, 4, 5}
    s2 := []int{7, 8,9,10}
    s3 := MergeSlice.Mix(s1, s2)
    fmt.Println(s3)
}

// ->  [1 7 2 8 3 9 4 10 5]

みたいな感じです。 なんでこれをやりたかったかというと、 2つの配列に入った処理を一定時間に按分して処理させたくて、 かつ、同じタイミングでそれぞれの処理が実行されたくなかったからです。

例えばgoroutineでそれぞれを並列実行すると 配列の数が同じだった場合は、実行タイミングが近くなりすぎてしまいました。

ライブラリがなかったので、作成しました。

func Mix(slice1 []int, slice2 []int) []int {
    var resp []int
    // ゼロチェック、どちらかが0なら、もう一つが返却される
    if len(slice1) == 0 {
        return slice2
    } else if len(slice2) == 0 {
        return slice1
    }

    long, short, step := checkSlice(slice1, slice2)
    
    // 返却されるスライスは2つの合計値の値を持つ
    goal := len(long)+len(short)
    for i := 1; i <= goal; i++ {
        if i%(step+1) == 0 {
            if len(short) != 0 {
                resp = append(resp, short[0])
                short = short[1:]
            } else {
                resp = append(resp, long[0])
                long = long[1:]
            }
        } else {
            resp = append(resp, long[0])
            long = long[1:]
        }
    }
    return resp
}
func checkSlice(s1 []int, s2 []int) ([]int, []int, int) {
    // 大きい方の配列を判定し、大きい配列、小さい配列、小さい配列の間隔を返します。
    if len(s1) > len(s2) {
        return s1, s2, int(len(s1) / len(s2))
    } else {
        return s2, s1, int(len(s2) / len(s1))
    }
}

GitHubにもアップしています。 Qiitaはこちら