2017-01-04 3 views
1

私はmethods hereを調べましたが、私が探しているものを見つけることができません。私はスウィフトの新しいアイスです。私はキー値のセットに基づいて、好ましくはループなしで辞書からサブセットを抽出したいと思う。例えばスウィフト3のサブセットを抽出する方法

私のキーセットタイプSet<String>であり、私はタイプDictionary<String, CustomObject>の辞書を持っている場合、私はセット内のキーに関連付けられている唯一のキーと値のペアが含まれているタイプDictionary<String, CustomObject>の新しい辞書を作成したいです弦の

Dictionary<String, CustomObj>()を初期化し、元のディクショナリにセット内の各文字列に値が含まれているかどうかを確認し、新しいディクショナリにキーと値のペアを追加することでループをforループで行うことができます。しかし、これを行うにはより効率的でエレガントな方法があるのだろうかと思います。

キーの配列でより良い方法があれば、セットの代わりに配列の配列でサブセットを見つけることができます。

多くの感謝!

+0

@AntonBronnikovのおかげで、あなたは明確でした - 「やること」によって、あなたは、反復プロセスを意味ですか? – jeanmw

答えて

0

あなたの前提は正しいですが、必要なものを達成するためのより簡潔な/迅速な方法があります。最初の有効な要素をフィルタリングし、次いで濾過要素で辞書をバック構築、2つの段階で

let subDict = originalDict.reduce([String: CustomObject]()) { 
    guard mySet.contains($1.key) else { return $0 } 
    var d = $0 
    d[$1.key] = $1.value 
    return d 
} 

または、:あなたは、reduce経由スウィフトで利用可能な関数型プログラミングの概念を、それを行うことができる。例えば

var filteredDict = [CustomObject]() 
mySet.forEach { filteredDict[$0] = originalDict[$0] } 
012:

let filteredDict = originalDict.filter { mySet.contains($0.key) } 
    .reduce([CustomObject]()){ var d = $0; d[$1.key]=$1.value; return d } 

forEachする濾過辞書を構築するためにも使用することができます

、しかし結果は、それが不変となり、それが良いでしょう:

let filteredDict: [String:CustomObject] = { 
    var result = [String:CustomObject]() 
    mySet.forEach { filteredDict2[$0] = originalDict[$0] } 
    return result 
}() 
+3

これは「迅速」と見ることができますが、各縮小ステップで新しい辞書が作成されるため、非常に効果的です。 https://airspeedvelocity.net/2015/08/03/arrays-linked-lists-and-performance/を比較してください。 –

+0

@ MartinRあなたが正しいですが、私はこの問題を抱えてはならないいくつかのソリューションを追加しました。 BTW、非常に洞察力の記事リンクのおかげで、。 – Cristik

+0

完璧な、ちょうど私が探していたもの。ありがとう! – jeanmw

0

ダミータイプ:

:あなたは、キーの特定のセットに基づいて、やり方を「交差」に(代わりに新しいものを作成する)元の辞書を変異したい場合には

struct CustomObject { 
    let foo: Int 
    init(_ foo: Int) { self.foo = foo } 
} 

let keySet = Set(["foo", "baz"]) 
var dict = ["foo": CustomObject(1), "bar": CustomObject(2), 
      "baz": CustomObject(3), "bax": CustomObject(4)] 

Set(dict.keys).subtracting(keySet).forEach { dict.removeValue(forKey: $0) } 

print(dict) // ["foo": CustomObject(foo: 1), "baz": CustomObject(foo: 3)] 
関連する問題