質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • Go

    511questions

    Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

golangで配列の要素をフィルターしたいです

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 825

DDxlk

score 115

ヤリタイコト

golangで

src := [...]int{1, 2, 3, 4, 5}

filter := [...]int{3, 5}


この二つの配列の被っている要素だけを抜き出して配列にしたいです。(数学で言うsrc ∩ filter)
一番ハイパフォーマンスな方法を教えてください

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • ozwk

    2017/12/20 12:17

    {1,1,2}と{1}のとき結果はどうしたいですか?{1,1} or {1}?

    キャンセル

  • DDxlk

    2017/12/20 12:46

    重複した場合は{1}としていただきたいです

    キャンセル

回答 1

checkベストアンサー

0

書いてて飽きてきてしまったのでこれが最速かどうかは分かりませんが、ベンチマークコードも載せておきます。

package common

import (
    "reflect"
    "sort"
    "testing"
)

func makeCommon(lhs, rhs []int) []int {
    // 出現回数
    m := map[int]int{}

    // 存在しない時だけ1にする
    // LHS で2回発生しても1
    for _, v := range lhs {
        if _, ok := m[v]; !ok {
            m[v] = 1
        }
    }

    // 存在する時だけ2にする
    for _, v := range rhs {
        if _, ok := m[v]; ok {
            m[v] = 2
        }
    }
    ret := []int{}
    for i := range m {
        if m[i] > 1 {
            ret = append(ret, i)
        }
    }
    sort.Ints(ret)
    return ret
}

func TestMakeCommon(t *testing.T) {
    tests := []struct {
        lhs  []int
        rhs  []int
        want []int
    }{
        {lhs: []int{1, 2, 3, 4, 5}, rhs: []int{3, 5}, want: []int{3, 5}},
        {lhs: []int{1, 2, 2, 3, 4, 5}, rhs: []int{3, 5}, want: []int{3, 5}},
        {lhs: []int{1, 2, 3, 3, 4, 5}, rhs: []int{3, 5}, want: []int{3, 5}},
        {lhs: []int{1, 1, 1}, rhs: []int{1, 1}, want: []int{1}},
        {lhs: []int{1, 2, 4, 5}, rhs: []int{3, 5}, want: []int{5}},
        {lhs: []int{1, 2, 4}, rhs: []int{3, 5}, want: []int{}},
        {lhs: []int{}, rhs: []int{3, 5}, want: []int{}},
        {lhs: []int{1, 2}, rhs: []int{}, want: []int{}},
        {lhs: []int{}, rhs: []int{}, want: []int{}},
    }

    for _, tt := range tests {
        got := makeCommon(tt.lhs, tt.rhs)
        if !reflect.DeepEqual(got, tt.want) {
            t.Fatalf("want %v but got %v", tt.want, got)
        }
    }
}

func BenchmarkMakeCommon(b *testing.B) {
    lhs := make([]int, b.N)
    rhs := make([]int, b.N/2)
    for i := 0; i < b.N; i++ {
        lhs[i] = i * 2
    }
    for i := 0; i < b.N/2; i++ {
        rhs[i] = i * 3
    }
    b.ResetTimer()
    makeCommon(lhs, rhs)
}

common_test.go などに保存して

$ go test -bench .
goos: windows
goarch: amd64
BenchmarkMakeCommon-4            5000000               396 ns/op
PASS
ok      _/C_/dev/go-sandbox/dup 2.482s

で実行して下さい。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.50%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Go

    511questions

    Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。