Массивы в Swift поддерживают оператор + = для добавления содержимого одного массива в другой. Есть ли простой способ сделать это для словаря?
например:
var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]
var combinedDict = ... (some way of combining dict1 & dict2 without looping)
dictionary
swift
rustyshelf
источник
источник
fromDict.forEach {intoDict[$0] = $1}
Ответы:
Вы можете определить
+=
оператор дляDictionary
, например,источник
@assignment
иreturn
, ты уже мутируешь налево. Редактировать: на самом деле, хотя я не получаю ошибок, я думаю, что@assignment
должен остаться.func +=<K, V> (inout left: [K : V], right: [K : V]) { for (k, v) in right { left[k] = v } }
public static func +=(lhs: inout [Key: Value], rhs: [Key: Value]) { rhs.forEach({ lhs[$0] = $1}) }
В Swift 4 нужно использовать
merging(_:uniquingKeysWith:)
:Пример:
источник
[NSMutableDictionary addEntriesFromDictionary:]
.Как насчет
Это добавляет все ключи и значения dict2 в dict1.
источник
Closure tuple parameter '(key: _, value: _)' does not support destructuring
(по крайней мере, на момент написания этой статьи). Можно было бы реструктурировать замыкание в соответствии с [этим ответом stackoverflow] ( stackoverflow.com/questions/44945967/… ):В настоящее время, глядя на Справочник стандартной библиотеки Swift для словаря, нет способа легко обновить словарь другим.
Вы можете написать расширение, чтобы сделать это
источник
Swift 4 обеспечивает
merging(_:uniquingKeysWith:)
, поэтому для вашего случая:Сокращенное закрытие возвращается
$1
, поэтому значение dict2 будет использоваться в случае конфликта с ключами.источник
- (void)addEntriesFromDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary;
. Что касается того, что делать с дубликатами, в нем говорится: «Если оба словаря содержат один и тот же ключ, предыдущему объекту-значению получающего словаря для этого ключа отправляется сообщение об освобождении, и объект нового значения занимает его место». версия Swift или в слиянии (_: uniquingKeysWith :), возвращающая второе значение,$1
такая же, как и вaddEntriesFromDictionary
случае с.Он не встроен в библиотеку Swift, но вы можете добавить то, что хотите, с перегрузкой операторов, например:
Это перегружает
+
оператор для словарей, которые теперь можно использовать для добавления словарей с+
оператором, например:источник
map
первымfor (k, v)...
циклом и отбросить его, если объявитеleft
параметр как,var
а затем просто скопируйтеright
в него значения.+
инфиксного оператора.+
перегрузка оператора не является методомDictionary
, это простая функция. Изменения, которые вы вносите в переменныйleft
параметр, не будут видны за пределами функции.Свифт 3:
источник
func merged(with dictionary: Dictionary<Key,Value>) -> Dictionary<Key,Value> {
var copy = self
dictionary.forEach { copy.updateValue($1, forKey: $0) }
return copy
}
Swift 2.0
источник
union
Функция имеет значение , переданное в него бытьvar
, смысл скопированного словаря может быть мутировал. Это немного чищеfunc union(dictionary: Dictionary) -> Dictionary { var dict2 = dictionary; dict2.unionInPlace(self); return dict2 }
, хотя бы на одну строчку.var dictionary = dictionary
. Отсюда: github.com/apple/swift-evolution/blob/master/proposals/…<Key, Value>
к нимDictionary
s.Неизменный
Я предпочитаю комбинировать / объединять неизменяемые словари с
+
оператором, поэтому я реализовал это следующим образом:изменчивый
источник
right.reduce(left)
, по крайней мере, это ожидаемое поведение IMO (и это поведение вашего второго примера) - т.е.["A":1] + ["A":2]
должен вывести["A":2]
Нет необходимости иметь какие-либо словарные расширения сейчас. Словарь Swift (Xcode 9.0+) имеет функциональность для этого. Посмотрите здесь . Ниже приведен пример того, как его использовать
источник
oldDictionary.merge(newDictionary) { $1 }
Более читаемый вариант с использованием расширения.
источник
Вы можете попробовать это
источник
Вы также можете использовать уменьшить, чтобы объединить их. Попробуйте это на детской площадке
источник
d
иp
?Я рекомендую библиотеку SwifterSwift . Однако, если вы не хотите использовать всю библиотеку и все ее замечательные дополнения, вы можете просто использовать расширение словаря:
Свифт 3+
источник
Вы можете перебирать комбинации Key Value для значения, которое хотите объединить, и добавлять их с помощью метода updateValue (forKey :):
Теперь все значения словаря два добавлены в словарь один.
источник
То же, что и ответ @ farhadf, но принят для Swift 3:
источник
Swift 3, расширение словаря:
источник
Некоторые еще более упорядоченные перегрузки для Swift 4:
источник
Вы можете добавить
Dictionary
расширение как это:Тогда использование так же просто, как следующее:
Если вы предпочитаете структуру , которая также включает в себя несколько более удобных функций , а затем фотографии HandySwift . Просто импортируйте его в свой проект, и вы сможете использовать приведенный выше код, не добавляя в проект никаких расширений .
источник
Больше нет необходимости в расширении или дополнительном функционале. Вы можете написать так:
источник
Ты можешь использовать,
источник
Вы можете использовать функцию bridgeToObjectiveC (), чтобы сделать словарь NSDictionary.
Будет похоже на следующее:
Затем вы можете преобразовать NSDictionary (объединить) обратно или сделать что-нибудь еще.
источник
В результате получается NSMutableDictionary, а не типизированный словарь Swift, но синтаксис для его использования тот же (
out["a"] == 1
в данном случае), поэтому у вас возникнет проблема только при использовании стороннего кода, который ожидает словарь Swift, или действительно нужна проверка типа.Короткий ответ здесь заключается в том, что вы действительно должны зацикливаться. Даже если вы не введете его явно, это будет делать вызываемый вами метод (addEntriesFromDictionary: здесь). Я бы посоветовал, если вам немного непонятно, почему вы должны подумать о том, как объединить листовые узлы двух B-деревьев.
Если вам действительно нужен взамен собственный тип словаря Swift, я бы предложил:
Недостатком этого подхода является то, что индекс словаря - как бы он ни был - может быть перестроен несколько раз в цикле, поэтому на практике это примерно в 10 раз медленнее, чем подход NSMutableDictionary.
источник
Все эти ответы сложны. Это мое решение для Swift 2.2:
источник
Мои потребности были разными, мне нужно было объединять неполные вложенные наборы данных без зазубрин.
Это было сложнее, чем я хотел. Задача состояла в отображении динамической типизации в статическую, и я использовал протоколы для решения этой проблемы.
Также стоит отметить, что когда вы используете буквальный синтаксис словаря, вы фактически получаете базовые типы, которые не воспринимают расширения протокола. Я прервал свои усилия, чтобы поддержать их, так как не мог легко найти подтверждение однородности элементов коллекции.
источник
Swift 2.2
источник
Я бы просто использовал библиотеку Dollar .
https://github.com/ankurp/Dollar/#merge---merge-1
Объединяет все словари вместе, и последний словарь переопределяет значение для данного ключа
источник
Вот хорошее расширение, которое я написал ...
использовать:
Тогда dict1 будет изменен на
источник