2017-01-04 5 views
1

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

Например, если мой ключ Set имеет тип Set<String> и у меня есть словарь типа Dictionary<String, CustomObject>, я хотел бы создать новый словарь типа Dictionary<String, CustomObject>, содержащий только пары ключ-значение, связанное с ключами в Комплексе Струнов.

Я вижу, что я мог бы сделать это с помощью цикла for, инициализируя новый Dictionary<String, CustomObj>(), проверяя, содержит ли исходный словарь значение в каждой строке в наборе и добавляет пары ключ-значение в новый словарь. Мне интересно, есть ли более эффективный/элегантный способ сделать это, однако.

Я был бы открыт для поиска подмножества с массивом строк вместо набора, если есть лучший способ сделать это с помощью массива ключей.

Большое спасибо! Тип

+0

@AntonBronnikov спасибо, не могли бы вы уточнить - на «сделать это» вы имеете в виду процесс итераций? – jeanmw

ответ

0

Ваше предположение верно, существует более сжатый/быстрый способ выполнить то, что вам нужно.

Например, вы можете сделать это с помощью reduce, функциональной концепции программирования, доступные в Swift:

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

Или, в два этапа, первый фильтрование действительные элементы, а затем строить назад словарь с отфильтрованных элементов :

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

forEach также может быть использован для построения отфильтрованный словаря:

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

, однако результат будет хорошим это было бы неизменны:

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

Это может выглядеть «swift-ish», но очень неэффективно, потому что на каждом этапе восстановления создается новый словарь. Сравните https://airspeedvelocity.net/2015/08/03/arrays-linked-lists-and-performance/. –

+0

@MartinR вы правы, я добавил еще несколько решений, которые не должны страдать от этой проблемы. Кстати, спасибо за ссылку на статью, очень проницательный. – 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)] 

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

  • Нет связанных вопросов^_^