As matrizes no Swift oferecem suporte ao operador + = para adicionar o conteúdo de uma matriz a outra. Existe uma maneira fácil de fazer isso em um dicionário?
por exemplo:
var dict1 = ["a" : "foo"]
var dict2 = ["b" : "bar"]
var combinedDict = ... (some way of combining dict1 & dict2 without looping)
dictionary
swift
enferrujado
fonte
fonte
fromDict.forEach {intoDict[$0] = $1}
Respostas:
Você pode definir um
+=
operador paraDictionary
, por exemplo,fonte
@assignment
ereturn
, você já está mudando para a esquerda. Edit: na verdade, mesmo que eu não receba erros, acho que@assignment
deveria ficar.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}) }
No Swift 4, deve-se usar
merging(_:uniquingKeysWith:)
:Exemplo:
fonte
[NSMutableDictionary addEntriesFromDictionary:]
.E se
Isso adiciona todas as chaves e valores do dict2 no dict1.
fonte
Closure tuple parameter '(key: _, value: _)' does not support destructuring
(pelo menos no momento da redação deste artigo). Seria necessário reestruturar o fechamento de acordo com [esta resposta do stackoverflow] ( stackoverflow.com/questions/44945967/… ):Atualmente, observando a Referência da biblioteca padrão da Swift para o dicionário, não há como atualizar facilmente um dicionário com outro.
Você pode escrever uma extensão para fazer isso
fonte
O Swift 4 fornece
merging(_:uniquingKeysWith:)
, portanto, para o seu caso:O fechamento abreviado retorna
$1
, portanto, o valor do dict2 será usado quando houver um conflito com as chaves.fonte
- (void)addEntriesFromDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary;
. Com relação ao que fazer com duplicatas, ele afirma que: "Se os dois dicionários contiverem a mesma chave, o objeto de valor anterior do dicionário receptor para essa chave receberá uma mensagem de liberação e o novo objeto de valor tomará seu lugar". a versão Swift, ou em mesclagem (_: uniquingKeysWith :), retornando o segundo valor,,$1
é igual ao queaddEntriesFromDictionary
faz.Ele não está incorporado na biblioteca Swift, mas você pode adicionar o que deseja com a sobrecarga do operador, por exemplo:
Isso sobrecarrega o
+
operador de Dicionários, que agora você pode usar para adicionar dicionários ao+
operador, por exemplo:fonte
map
e largar o primeirofor (k, v)...
loop se declarar oleft
parâmetro comovar
e depois copiar valoresright
nele.+
operador infix.+
sobrecarga do operador também não é um métodoDictionary
, é uma função simples. As alterações feitas em umleft
parâmetro variável não seriam visíveis fora da função.Swift 3:
fonte
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
fonte
union
função tem o valor passado para ser avar
, o que significa que o dicionário copiado pode ser alterado. É um pouco mais limpo do quefunc union(dictionary: Dictionary) -> Dictionary { var dict2 = dictionary; dict2.unionInPlace(self); return dict2 }
, mesmo que apenas por uma linha.var dictionary = dictionary
. A partir daqui: github.com/apple/swift-evolution/blob/master/proposals/…<Key, Value>
asDictionary
.Imutável
Eu prefiro combinar / unir dicionários imutáveis com
+
operador, então eu o implementei como:Mutável
fonte
right.reduce(left)
, pelo menos, esse é o comportamento esperado imo (e é o comportamento do seu segundo exemplo) - ie.["A":1] + ["A":2]
saída["A":2]
Não há necessidade de extensões de dicionário agora. O dicionário Swift (Xcode 9.0+) possui uma funcionalidade para isso. Dê uma olhada aqui . Abaixo, aqui está um exemplo de como usá-lo
fonte
oldDictionary.merge(newDictionary) { $1 }
Uma variante mais legível usando uma extensão.
fonte
Você pode tentar isso
fonte
Você também pode usar reduzir para mesclá-los. Tente isso no parquinho
fonte
d
ep
?Eu recomendo a Biblioteca SwifterSwift . No entanto, se você não quiser usar a biblioteca inteira e todas as suas ótimas adições, basta usar a extensão do Dictionary:
Swift 3+
fonte
Você pode iterar sobre as combinações de valores-chave do valor que deseja mesclar e adicioná-las através do método updateValue (forKey :):
Agora todos os valores de dictionaryTwo foram adicionados ao dictionaryOne.
fonte
O mesmo que a resposta de @ farhadf, mas adotada para o Swift 3:
fonte
Swift 3, extensão de dicionário:
fonte
Algumas sobrecargas ainda mais simplificadas para o Swift 4:
fonte
Você pode adicionar uma
Dictionary
extensão como esta:Então, o uso é tão simples quanto o seguinte:
Se você preferir uma estrutura que também inclua alguns recursos mais úteis , consulte o HandySwift . Basta importá-lo para o seu projeto e você pode usar o código acima sem adicionar extensões ao projeto.
fonte
Não há necessidade de extensão ou qualquer função extra. Você pode escrever assim:
fonte
Você pode usar,
fonte
Você pode usar a função bridgeToObjectiveC () para tornar o dicionário um NSDictionary.
Será como o seguinte:
Em seguida, você pode converter o NSDictionary (combinar) de volta ou fazer o que quiser.
fonte
O resultado é um NSMutableDictionary, não um dicionário do tipo Swift, mas a sintaxe para usá-lo é a mesma (
out["a"] == 1
nesse caso); portanto, você só terá um problema se estiver usando um código de terceiros que espera um dicionário Swift ou realmente precisa da verificação de tipo.A resposta curta aqui é que você realmente precisa fazer um loop. Mesmo se você não estiver inserindo explicitamente, é isso que o método que você está chamando (addEntriesFromDictionary: aqui) fará. Eu sugiro que, se você não souber ao certo por que seria esse o caso, considere como mesclaria os nós das folhas de duas árvores-B.
Se você realmente precisa de um tipo de dicionário nativo Swift em troca, sugiro:
A desvantagem dessa abordagem é que o índice do dicionário - por mais que seja feito - pode ser reconstruído várias vezes no loop, portanto, na prática, isso é cerca de 10 vezes mais lento que a abordagem NSMutableDictionary.
fonte
Todas essas respostas são complicadas. Esta é a minha solução para o Swift 2.2:
fonte
Minhas necessidades eram diferentes, eu precisava mesclar conjuntos de dados aninhados incompletos sem atrapalhar.
Isso foi mais difícil do que eu queria que fosse. O desafio estava no mapeamento da digitação dinâmica para a estática, e usei protocolos para resolver isso.
Também digno de nota é que quando você usa a sintaxe literal do dicionário, na verdade você obtém os tipos de fundação, que não capturam as extensões de protocolo. Abortei meus esforços para apoiá-los, pois não achei fácil validar a uniformidade dos elementos da coleção.
fonte
Swift 2.2
fonte
Eu usaria apenas o dólar biblioteca .
https://github.com/ankurp/Dollar/#merge---merge-1
Mescla todos os dicionários e o último dicionário substitui o valor em uma determinada chave
fonte
Aqui está uma boa extensão que escrevi ...
usar:
Em seguida, dict1 será modificado para
fonte