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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

3回答

3614閲覧

配列から重複している値を取得したい。

退会済みユーザー

退会済みユーザー

総合スコア0

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/08/06 10:26

編集2018/08/07 08:23

いつもお世話になります。
配列から重複している値を取り出す際に簡潔な方法はないでしょうか?

swift

1let array = ["A", "B", "B", "B", "C", "D", "D"] 2 3// => 重複している配列要素 = ["B", "D"] を取得したい。 4

現状は、下記のような考え方ですすめていて、面倒だなと…。

swift

1 2let array = ["A", "B", "B", "B", "C", "D", "D"] 3 4//重複要素を除去する 5let orderSet = NSOrderedSet(array: array) 6let uniqueArray = orderedSet.array as! [String] 7 8print(uniqueArray) // => ["A", "B", "C", "D"] 9 10/* 11arrayの要素["A", "B", "B", "B", "C", "D", "D"] から 12uniqueArrayの要素["A", "B", "C", "D"]を1つづつ削除していく。 13*/ 14 15// => ["B","B","D"] 16 17// もう一度重複要素を除去する => ["B", "D"] 18 19

解決方法&備忘録

その1

swift

1let array = ["A", "B", "B", "B", "C", "D", "D"] 2 3// 重複している要素の取得 4var set = Set<String>() 5let duplicatedEArray = NSOrderedSet(array: array.filter { !set.insert($0).inserted }).array as! [String] 6// => ["B", "D"] 7 8// ユニークな要素の取得 9let noDuplicatedArray = NSOrderedSet(array: array).array as! [String] 10let UniqueEArray = noDuplicatedArray.filter{ v in return !duplicatedEArray.contains(v) } 11// => ["A", "C"]

その2

swift

1let array = ["A", "B", "B", "B", "C", "D", "D"] 2 3// 重複している要素の取得 4let duplicatedEArray = Array(Dictionary(grouping: array) {$0}.filter {$0.value.count > 1}.keys) 5// => ["B", "D"] 6 7// ユニークな要素の取得 8let UniqueEArray = Array(Dictionary(grouping: array) {$0}.filter {$0.value.count == 1}.keys) 9// => ["A", "C"]

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

swift

1let array = ["A", "B", "B", "B", "C", "D", "D"] 2print(array.reduce(into: [String:Int]()) {$0[$1] = ($0[$1] ?? 0) + 1}.filter {$0.1 > 1}.keys) 3//=> ["B", "D"]

と、考えてからdaisuke7さんの回答に気付く‥。

Dictionary(grouping:)使用

さっそく吸収w

swift

1print(Dictionary(grouping: array) {$0}.filter {$0.value.count > 1}.keys)

これくらいのシンプルさなら(見た目的に)大丈夫?

投稿2018/08/07 01:35

編集2018/08/07 02:03
fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/08/07 08:31 編集

回答ありがとうございます。上は初見で自分では理解不能と思われますが、下はわかりやすいです。 > を== に変えるだけでユニークな要素が取れると思いよろこんで試しましたが動きませんでした。 --- error --- playgroundに貼ったところ、 error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=EXC_I386_GPFLT). The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation. ------ let duplicatedEArray = Array(Dictionary(grouping: array) {$0}.filter {$0.value.count > 1}.keys) としたところ動きましたが、直し方はこんな感じていいのでしょうか? let UniqueEArray = Array(Dictionary(grouping: array) {$0}.filter {$0.value.count == 1}.keys) ↑重複取得・ユニーク取得のセットで、使い勝手がよさそうです。
fuzzball

2018/08/07 08:31 編集

テストデータではなく、実際のデータを食わせるとエラーになるということでしょうか?【追記】あぁ、すみません。PlayGroundでの話ですね。
退会済みユーザー

退会済みユーザー

2018/08/07 08:32 編集

いえ、まだ理解作業中なので、そのままplaygroundに貼り付けただけです。
fuzzball

2018/08/07 08:34

Array()で囲ったということですかね?それでOKだと思います。(上の回答も最初はArrayで囲ってました)
退会済みユーザー

退会済みユーザー

2018/08/07 08:36

ありがとうございます。
guest

0

ベストアンサー

swift

1let array = ["A", "B", "B", "B", "C", "D", "D"] 2 3var set = Set<String>() 4let repeated = NSOrderedSet(array: array.filter { !set.insert($0).inserted }).array

ちょっと気持ち悪いけど、これが最速/最短かな?

投稿2018/08/06 13:05

MasakiHori

総合スコア3384

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/08/07 08:34 編集

回答ありがとうございます。 値が重複してる前提なのでSetは使うことはないと思ってたのですが、そう(!Set)使うですか。なるほどです。たしかになんかもやもやして気持ち悪いような気もします。
guest

0

Swift

1let array = ["A", "B", "B", "B", "C", "D", "D"] 2let dic = Dictionary(grouping: array) { $0 } 3print("dictionary:(dic)") 4let duplicated = dic.filter { $1.count > 1 } .map { $0.0 } .sorted() 5print("array:(array) -> duplicated:(duplicated)") 6

(結果)

dictionary:["A": ["A"], "C": ["C"], "D": ["D", "D"], "B": ["B", "B", "B"]] array:["A", "B", "B", "B", "C", "D", "D"] -> duplicated:["B", "D"]

辞書を作って、1個よりも多いのだけに絞って、その文字を取り出してソートしています。

投稿2018/08/06 10:59

編集2018/08/06 11:18
daisuke7

総合スコア1563

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/08/06 15:11 編集

回答ありがとうございます。 辞書にする考えは浮かびませんでした。ためになります。
退会済みユーザー

退会済みユーザー

2018/08/07 08:12

あとから気づいたのですが、> を == にすると一意の要素が取得できるんですね。使い勝手がよさそうです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問