Keyの配列とDictionaryを見比べて、配列になくてDictionaryにある値を削除する
タイトルが長く、わかりにくいです
つまり何がしたいの?
ここに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の配列でください」ということですね
最後に
ふと思ってやってみたが、簡単に作ることができました。
もっと簡単にできるとか、なにか間違いがありましたら教えてください
あと、関数のネーミングに不安が残りました
Author And Source
この問題について(Keyの配列とDictionaryを見比べて、配列になくてDictionaryにある値を削除する), 我々は、より多くの情報をここで見つけました https://qiita.com/hmhmsh/items/83e95fd2eb082d212bd8著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .