Swift配列に演算(ユニオン、交差)を設定しますか?


100

2つの配列に対して集合演算を実行するために、またはそのようなロジックを自分で(理想的には機能的かつ可能な限り効率的に)実装するために使用できる標準ライブラリ呼び出しはありますか?


自分でやりたい場合は、辞書の上にセットを実装できます。
CodaFi 2014

@CodaFiキーを使用して一意性を確保するということですか?
devios1 2014

`Dictionary <String、Void>を使用できますか?
David Berry

回答:


184

はい、SwiftにはSetクラスがあります。

let array1 = ["a", "b", "c"]
let array2 = ["a", "b", "d"]

let set1:Set<String> = Set(array1)
let set2:Set<String> = Set(array2)

Swift 3.0以降では、次のようにセットの操作を実行できます。

firstSet.union(secondSet)// Union of two sets
firstSet.intersection(secondSet)// Intersection of two sets
firstSet.symmetricDifference(secondSet)// exclusiveOr

Swift 2.0は配列引数を計算できます:

set1.union(array2)       // {"a", "b", "c", "d"} 
set1.intersect(array2)   // {"a", "b"}
set1.subtract(array2)    // {"c"}
set1.exclusiveOr(array2) // {"c", "d"}

Swift 1.2+はセットで計算できます:

set1.union(set2)        // {"a", "b", "c", "d"}
set1.intersect(set2)    // {"a", "b"}
set1.subtract(set2)     // {"c"}
set1.exclusiveOr(set2)  // {"c", "d"}

カスタム構造体を使用している場合は、Hashableを実装する必要があります。

Swift 2.0アップデートのコメントでMichael Sternに感謝します。

Hashable情報のコメントのAmjad Husseiniに感謝します。


8
Swift 2.0以降では、これらの関数の引数として配列を渡すことができることに注意してください。したがって、set1.union(array2)そしてset1.exclusiveOr(array2)上に示した形態に加えて、両方の正当です。
Michael Stern

5つの配列を交差させる場合はどうでしょうか。または6?アレイの数が不明な場合はどうなりますか?
Nathan McKaskle、2015

2
@Nathan設定操作によって異なります。たとえば、セットユニオンとセットインターセクションは交換可能かつ結合的であるため、反復またはチェーンを使用して多くのセットを処理できます。または、Set union_all(...)やintersect_all(...)などの変数引数を使用するカスタムメソッドを作成することもできます。
joelparkerhenderson

配列に重複する値が含まれている場合はどうですか。たとえば、$ 0が$ 1のアナグラムで、入力文字が重複している可能性があるかどうかを判断する場合はどうでしょうか。
Dave Kliman 2016年

1
カスタム構造体を使用している場合は、Hashableに準拠する必要があります。複雑な構造体がある場合は煩わしいかもしれません
Amjad Husseini

0

標準のライブラリ呼び出しはありませんが、ExSwiftライブラリを確認することをお勧めします。これには、差分、交差、和集合など、配列に関する新しい関数が多数含まれています。


1
注意書き:私はSwift 1.xでは問題なくExSwiftを使用していましたが、Swift 2.xではかなり壊れているようで、この記事の執筆時点では数か月間更新されていません。もっと注目されるかもしれないフォークがたくさんあります。
Robin Macharg、2015


0

私が知っている最も効率的な方法は、godel数を使用することです。godelエンコーディング用のGoogle。

アイデアはそうです。N個の可能な数があり、それらのセットを作成する必要があるとします。たとえば、N = 100,000で、{1,2,3}、{5、88、19000}などのセットを作成したいとします。

アイデアは、メモリにN個の素数のリストを保持し、与えられたセット{a、b、c、...}に対して次のようにエンコードすることです。

 prime[a]*prime[b]*prime[c]*...

したがって、セットをBigNumberとしてエンコードします。BigNumbersを使用した操作は、Integerを使用した操作よりも低速であるにもかかわらず、非常に高速です。

2セットA、Bを結合するには、

  UNITE(A, B) = lcm(a, b)

AとBはセットと両方の数なので、AとBの最小公倍数。

交差点を作るには

 INTERSECT(A, B) = gcd (a, b)

最大公約数。

等々。

このエンコーディングはゴデライゼーションと呼ばれ、グーグルでより多くのことができます。Fregeのロジックを使用して書かれた算術のすべての言語は、この方法で数値を使用してエンコードできます。

操作を取得するにはメンバーですか?とても簡単です

ISMEMBER(x, S) = remainder(s,x)==0

枢機卿を取得するには、少し複雑です-

CARDINAL(S) = # of prime factors in s

セットを表す数Sを素因数の積で分解し、それらの指数を追加します。セットが重複を許可しない場合、すべての指数が1になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.