🎅

【Swift】Boolの配列の論理和/論理積を取得したい

2024/12/13に公開
2

Boolの配列の論理和を取得したい...!

例えば、ある文字列が複数の文字列パターンのいずれかに当てはまっているかどうか知りたい場面を考えます。

let patterns = ["hoge", "fuga"]
let string = "hogehoge"
print(string.map({string.contains($0)})) // [true, false]

Bool型の配列は取れたけど、ここから論理和ってどうやってどうやって出せば...?
.reduce() をつかって .reduce(false, { $0 || $1 }) か...?

結論

SwiftLintがもっとナイスな提案をしてくれました。.contains(true) でイケる!

let bools = [true, false, false]
let result = bools.contains(true)
print("result:", result) // true

たしかに...!1つでも true が含まれていたら論理和も true やんけ!

論理積の場合はこんな感じ。

let bools = [true, true, false]
let result = !bools.contains(false)
print("result:", result) // true

最初の例なら、全てのパターンにマッチした文字列かどうかを調べたい時に使えるかも〜

(2024.12.18 追記)
論理積の場合は .allSatisfy() を使った方がスマートかもとuhooiさんにコメントで教えていただきました🙏圧倒的感謝...!

let bools = [true, true, false]
let result = bools.allSatisfy(true)
print("result:", result) // true

.contains()は一致する要素が見つかるとすぐに検査を終了するので、論理和には有効です。
しかし、論理積の場合は全ての要素を検査することになるので、.contains()にするメリットは特になさそうです。であれば.allSatisfy()を使った方がたしかにスマート...!

(追記ここまで)

おわりに

SwiftLintに命を救われました。
Swift Advent Calendar 2024 13日目の記事でした🎅

参考

https://github.com/realm/SwiftLint/issues/2583

Discussion

uhooiuhooi

論理積は !bools.contains(false) より bools.allSatisfy(true) のほうがスマートかも!
ref: https://developer.apple.com/documentation/swift/array/allsatisfy(_:)

RyommRyomm

たしかに...!論理積の場合は結局全ての要素を検査することになるので計算量から考えてもallSatisfyを使った方がよさそうですね:wow:
ありがとうございます、記事の方に反映させていただきます🙏!