2016-05-28 3 views
1

Как удалить ключ из словаря, где значение X? Мне нужна функция dictionary.removeKeyForValue (...).Удалить ключ из словаря для заданного значения

Я хотел бы оптимизировать следующий код. У меня есть текст, который связан с определенной категорией и словарем, который связывает все ключевые слова с категориями. Хотя мой текст уже классифицирован, я бы хотел проверить, не попадает ли он в другую категорию.

let text = "he said hello and then ran away" // This is taken from the "activity" category 
// Dictionary associating keywords to categories 
let categoryRules = ["hi" : "greeting", "hello" : "greeting", "jogging" : "activity", "joy" : "feeling"] 

let keywords = Array(categoryRules.keys) 
// Make out of text an Array of words. 
let textWordArray = text.lowercaseString.characters.split{$0 == " "}.map(String.init) 

// I SHOULDN'T HAVE TO GO THROUGH THE KEYS ASSOCIATED WITH "ACTIVITY" BECAUSE TEXT IS ALREADY IN IT. 
for keyword in keywords {  
    // If text contains the rule 
    if let index = textWordArray.indexOf(keyword) { 
     // Get the associated category 
     if let category = categoryRules[keyword] { 
      print("The text should fall into the category of \(category)") 
      break 
     } 
    } 
} 
+0

«Мне нужна функция dictionary.removeKeyForValue (...)». У этого плохой запах. Если вы считаете, что вам нужно что-то искать в словаре по _value_, вы неправильно построили словарь. – matt

ответ

4

Чтобы удалить все key сек из словаря с определенным value, вы можете использовать for цикл с where пунктом для выбора key с, чтобы удалить, а затем назначить nil удалить их:

var categoryRules = ["hi" : "greeting", "hello" : "greeting", "jogging" : "activity", "joy" : "feeling"] 

for (key, value) in categoryRules where value == "greeting" { 
    categoryRules[key] = nil 
} 

print(categoryRules) // ["jogging": "activity", "joy": "feeling"] 

Вы можете добавить removeKeysForValue, добавив расширение Dictionary, которое работает для значений Equatable (для сравнения d с ==):

extension Dictionary where Value: Equatable { 
    mutating func removeKeysForValue(value: Value) { 
     for (key, val) in self where val == value { 
      self[key] = nil 
     } 
    } 
} 

var categoryRules = ["hi" : "greeting", "hello" : "greeting", "jogging" : "activity", "joy" : "feeling"] 

categoryRules.removeKeysForValue("greeting") 

print(categoryRules) // ["jogging": "activity", "joy": "feeling"] 
1

Вот альтернативное решение, которое я нахожу, элегантный, который использует фильтры.

var categoryRules = ["hi" : "greeting", "hello" : "greeting", "jogging" : "activity", "joy" : "feeling"] 
let keysToRemove = dict.keys.filter { dict[$0]! == "greeting" } 

for key in keysToRemove { 
    dict.removeValueForKey(key) 
} 

// categoryRules = ["jogging": "activity", "joy": "feeling"] 

keysToRemove будет иметь «привет» и «Привет», потому что они соответствовали данному фильтру, имеющему значение «приветствие».


Edit:

О.П. отметил, что он хотел dictionary.removeKeyForValue() функцию. Вы можете создать расширение с вышеуказанным кодом, чтобы повысить читаемость и избежать дублирования кода, если вы планируете часто выполнять это действие.

Пример:

extension Dictionary { 
    mutating func removeKeysForValue(value: NSObject) { 
    let keysToRemove = self.keys.filter { self[$0]! as! NSObject == value } 

    for key in keysToRemove { 
     self.removeValueForKey(key) 
    } 
    } 
} 

var dict = ["hi" : "greeting", "hello" : "greeting", "jogging" : "activity", "joy" : "feeling"] 

dict.removeKeysForValue("greeting") // dict = ["jogging": "activity", "joy": "feeling"] 
0

Поскольку он будет принимать O (п) время, чтобы удалить ключи из словаря (где п является размер словаря) может быть лучшей идеей для создания список словарей (вместо одного). Каждый словарь исключает необходимые элементы. Поэтому при поиске значений из словаря вам просто нужно выбрать правильный словарь.

Это будет иметь лучшую производительность, а затем удалит ключи из словаря во время выполнения. Особенно, когда вы выполняете поиск несколько раз в циклах.

Смежные вопросы