Swift の配列で要素の出現回数を数えるには?
質問
私はこの例をいくつか見ましたが、それらはすべて、どの要素の出現をカウントしたいかを知っていることに依存しているようです。私の配列は動的に生成されるので、私はどの要素の出現をカウントしたいかを知る方法がありません(私はそれらのすべての出現をカウントしたい)。どなたかアドバイスをお願いします。
前もってありがとうございます。
EDIT
もっと明確に言うべきだったかもしれませんが、配列には複数の異なる文字列が含まれます(例えば
["FOO", "FOO", "BAR", "FOOBAR"]
foo、bar、foobarが何であるかを事前に知ることなく、出現回数を数えるにはどうしたらよいでしょうか。
どのように解決するのですか?
Swift 3とSwift 2です。
型の辞書を使用することができます。
[String: Int]
の各項目についてカウントを蓄積することができます。
[String]
:
let arr = ["FOO", "FOO", "BAR", "FOOBAR"]
var counts: [String: Int] = [:]
for item in arr {
counts[item] = (counts[item] ?? 0) + 1
}
print(counts) // "[BAR: 1, FOOBAR: 1, FOO: 2]"
for (key, value) in counts {
print("\(key) occurs \(value) time(s)")
}
を出力します。
BAR occurs 1 time(s)
FOOBAR occurs 1 time(s)
FOO occurs 2 time(s)
Swift 4です。
スウィフト 4
が導入されました (SE-0165)
のような操作で、辞書検索にデフォルト値を含めることができるようになりました。
+=
と
-=
のように、です。
counts[item] = (counts[item] ?? 0) + 1
になります。
counts[item, default: 0] += 1
これによって、カウントの操作を簡潔な1行で行うことができます。
forEach
:
let arr = ["FOO", "FOO", "BAR", "FOOBAR"]
var counts: [String: Int] = [:]
arr.forEach { counts[$0, default: 0] += 1 }
print(counts) // "["FOOBAR": 1, "FOO": 2, "BAR": 1]"
Swift 4:
reduce(into:_:)
Swift 4 では、新しいバージョンの
reduce
を使用する新しいバージョンを導入しました。
inout
変数を使用して結果を蓄積します。 これを使うと、カウントの作成が本当に1行になります。
let arr = ["FOO", "FOO", "BAR", "FOOBAR"]
let counts = arr.reduce(into: [:]) { counts, word in counts[word, default: 0] += 1 }
print(counts) // ["BAR": 1, "FOOBAR": 1, "FOO": 2]
またはデフォルトのパラメータを使用する。
let counts = arr.reduce(into: [:]) { $0[$1, default: 0] += 1 }
最後に、これを
Sequence
で呼び出せるようにします。
Sequence
を含む
Hashable
を含む項目
Array
,
ArraySlice
,
String
そして
String.SubSequence
:
extension Sequence where Element: Hashable {
var histogram: [Element: Int] {
return self.reduce(into: [:]) { counts, elem in counts[elem, default: 0] += 1 }
}
}
このアイデアは
この質問
に変更しましたが
計算されたプロパティ
. を拡張することを提案してくれた @LeoDabus に感謝します。
Sequence
の代わりに
Array
を使うことで、追加の型を拾うことができます。
例
print("abacab".histogram)
<ブロッククオート
["a": 3, "b": 2, "c": 1]
print("Hello World!".suffix(6).histogram)
<ブロッククオート
["l": 1, "!": 1, "d": 1, "o": 1, "W": 1, "r": 1]
print([1,2,3,2,1].histogram)
<ブロッククオート
[2: 2, 3: 1, 1: 2]
print([1,2,3,2,1,2,1,3,4,5].prefix(8).histogram)
<ブロッククオート
[1: 3, 2: 3, 3: 2]
print(stride(from: 1, through: 10, by: 2).histogram)
<ブロッククオート
[1: 1, 3: 1, 5: 1, 7: 1, 9: 1]
関連
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] JavaScript で配列に値が含まれているかどうかを確認するにはどうすればよいですか?
-
[解決済み] 配列からArrayListを作成する
-
[解決済み] 配列に特定のインデックスで項目を挿入する方法 (JavaScript)
-
[解決済み] PHPで配列から要素を削除する
-
[解決済み] UITableViewの選択を無効にするにはどうすればよいですか?
-
[解決済み] iOS7でスタイルUITableViewStyleGroupedを持つUITableViewの上部に余分なパディングがあるのはなぜですか?
-
[解決済み] swiftで電子メールアドレスを検証する方法は?
-
[解決済み】オブジェクトの配列を文字列のプロパティ値でソートする
-
[解決済み】配列に何かを追加する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
XCode のコンパイル例外を解決する clang: error: linker command failed with exit code 1
-
[解決済み] アトミック属性と非アトミック属性の違いは何ですか?
-
[解決済み] UITableViewの下にある余分なセパレータをなくす
-
[解決済み] Objective-Cで文字列が空かどうかをテストするにはどうすればよいですか?
-
[解決済み] UIViewController のビューが表示されているかどうかを確認する方法
-
[解決済み] iOS 13 のフルスクリーンでモーダルを表示する
-
[解決済み] UITextViewのサイズをコンテンツに合わせるには?
-
[解決済み] 16進カラーバリューの使用方法
-
[解決済み] ファイルはユニバーサル(3スライス)ですが、iOSの静的ライブラリのための(n)ARMv7-sスライスエラーが含まれていない、どうにかして回避するには?
-
[解決済み] ぼかしの入ったオーバーレイビューの作成