タイトルが長く、わかりにくいです![]()
つまり何がしたいの?
ここにStringの配列があります。
let keys = ["A", "B", "C", "D"]
Dictionaryもあります。
var dictionary = ["A": 0, "B": 1, "C": 2, "D": 3, "E": 4]
見比べると、"E"というkeyが、keys にはなくてdictionaryにはあります。
この"E"を削除したい![]()
どちらにもあるものを取得
dictionaryのkeyを取得して、keysに含まれるかを確認する。
keysに含まれるものだけの配列を取得できた
let keys = ["A", "B", "C", "D"]
var dictionary = ["A": 0, "B": 1, "C": 2, "D": 3, "E": 4]
let contains = dictionary.keys.filter { (key) -> Bool in
keys.contains(key)
}
print(contains) // ["B", "A", "C", "D"]
Dictionaryにしかないものを取得
先ほどの判定を逆にしたら良い。
dictionaryにしか含まれないものの配列を取得できた
let nocontains = dictionary.keys.filter { (key) -> Bool in
!keys.contains(key) // !をつける
}
print(nocontains) // ["E"]
Dictionaryにしかないものを削除
あとはdictionaryから削除するだけ。
nocontains.forEach { (removeKey) in
dictionary.removeValue(forKey: removeKey)
}
print(dictionary) // ["B": 1, "A": 0, "C": 2, "D": 3]
Dictionaryを拡張
ついでに、keysに含まれるものを削除する関数も作成
extension Dictionary {
// 引数の配列に含まれていないものを削除
// mutating func removeUnincludedValue(in keys: Array<Key>) {
// self.keys.filter { (key) -> Bool in
// !keys.contains(key)
// }.forEach { (removeKey) in
// self.removeValue(forKey: removeKey)
// }
// }
// 追記: コメント欄で教えてもらった
func removeUnincludedValue(in keys: Array<Key>) -> Dictionary<Key, Value> {
return self.filter { keys.contains($0.key) }
}
// 追記: コメント欄で教えてもらった
func filtered(byKeys keys: Array<Key>) -> Dictionary {
var newDictionary: Dictionary = [:]
var keysIterator = keys.makeIterator()
newDictionary.reserveCapacity(self.count)
while let key = keysIterator.next() {
if let value = self[key] {
newDictionary[key] = value
}
}
return newDictionary
}
// 追記: コメント欄で教えてもらった
mutating func filter(byKeys keys: [Key]) {
self = self.filtered(byKeys: keys)
}
// 追記: コメント欄で教えてもらった
// func filtered(keys: [Key]) -> Dictionary {
// return keys.reduce(into: [Key: Value]()) { dict, key in dict[key] = self[key] }
// }
// 追記: コメント欄で教えてもらったのを、swiftっぽく書いてみた
func filtered(keys: [Key]) -> Dictionary {
return keys.reduce(into: [Key: Value]()) { $0[$1] = self[$1] }
}
// 引数の配列に含まれているものを削除
// mutating func removeIncludedValue(in keys: Array<Key>) {
// self.keys.filter { (key) -> Bool in
// keys.contains(key)
// }.forEach { (removeKey) in
// self.removeValue(forKey: removeKey)
// }
// }
// 追記: もっと簡単に書けた
mutating func removeIncludedValue(in keys: Array<Key>) {
keys.forEach { (removeKey) in
self.removeValue(forKey: removeKey)
}
}
}
keysに含まれてないけど、dictionaryに含まれているものを削除
let keys = ["A", "B", "C", "D"]
var dictionary = ["A": 0, "B": 1, "C": 2, "D": 3, "E": 4]
dictionary.removeUnincludedValue(in: keys) // ["B": 1, "A": 0, "C": 2, "D": 3]
keysに含まれていて、dictionaryにも含まれているものを削除
let keys = ["A", "B", "C", "D"]
var dictionary = ["A": 0, "B": 1, "C": 2, "D": 3, "E": 4]
dictionary.removeIncludedValue(in: keys) // ["E": 4]
型が違う時はコンパイルエラーでるから安心
let keys = ["A", "B", "C", "D"]
var dictionary1 = [0: 0, 1: 1, 2: 2]
dictionary1.removeUnincludedValue(in: keys)
// cannot convert value of type '[String]' to expected argument type 'Array<Int>'
「dictionary1のkeyはIntなのでkeysはIntの配列でください」ということですね
最後に
ふと思ってやってみたが、簡単に作ることができました。
もっと簡単にできるとか、なにか間違いがありましたら教えてください
あと、関数のネーミングに不安が残りました![]()