Há alguma chamada de biblioteca padrão que eu possa usar para executar operações de conjunto em dois arrays ou implementar essa lógica sozinho (de preferência da maneira mais funcional e eficiente possível)?
Há alguma chamada de biblioteca padrão que eu possa usar para executar operações de conjunto em dois arrays ou implementar essa lógica sozinho (de preferência da maneira mais funcional e eficiente possível)?
Respostas:
Sim, Swift tem a Set
classe.
let array1 = ["a", "b", "c"]
let array2 = ["a", "b", "d"]
let set1:Set<String> = Set(array1)
let set2:Set<String> = Set(array2)
O Swift 3.0+ pode fazer operações em conjuntos como:
firstSet.union(secondSet)// Union of two sets
firstSet.intersection(secondSet)// Intersection of two sets
firstSet.symmetricDifference(secondSet)// exclusiveOr
O Swift 2.0 pode calcular em argumentos de matriz:
set1.union(array2) // {"a", "b", "c", "d"}
set1.intersect(array2) // {"a", "b"}
set1.subtract(array2) // {"c"}
set1.exclusiveOr(array2) // {"c", "d"}
O Swift 1.2+ pode calcular em conjuntos:
set1.union(set2) // {"a", "b", "c", "d"}
set1.intersect(set2) // {"a", "b"}
set1.subtract(set2) // {"c"}
set1.exclusiveOr(set2) // {"c", "d"}
Se você estiver usando structs personalizados, é necessário implementar Hashable.
Agradecimentos a Michael Stern nos comentários sobre a atualização do Swift 2.0.
Agradecimentos a Amjad Husseini nos comentários pela informação Hashable.
set1.union(array2)
e set1.exclusiveOr(array2)
são ambos legítimos, além dos formulários acima.
Não existem chamadas de biblioteca padrão, mas você pode querer dar uma olhada na biblioteca ExSwift . Inclui um monte de novas funções em Arrays, incluindo diferença, interseção e união.
Você pode querer seguir o mesmo padrão de Objective-C, que também não possui essas operações, mas há uma solução alternativa simples:
O método mais eficiente que conheço é o uso de números Godel. Google para codificação Godel.
A ideia é assim. Suponha que você tenha N números possíveis e precise fazer conjuntos deles. Por exemplo, N = 100.000 e deseja fazer conjuntos como {1,2,3}, {5, 88, 19000} etc.
A ideia é manter a lista de N números primos na memória e para um determinado conjunto {a, b, c, ...} você a codifica como
prime[a]*prime[b]*prime[c]*...
Portanto, você codifica um conjunto como um BigNumber. As operações com BigNumbers, apesar de serem mais lentas que as operações com Inteiros, ainda são muito rápidas.
Para unir 2 conjuntos A, B, você toma
UNITE(A, B) = lcm(a, b)
menor-comum-múltiplo de A e B como A e B são conjuntos e ambos números.
Para fazer o cruzamento, você pega
INTERSECT(A, B) = gcd (a, b)
maior divisor comum.
e assim por diante.
Essa codificação é chamada de godelização, você pode pesquisar mais no Google, toda a linguagem da aritmética escrita usando a lógica de Frege pode ser codificada usando números dessa forma.
Para obter a operação is-member? É muito simples --
ISMEMBER(x, S) = remainder(s,x)==0
Para obter o cardeal é um pouco mais complicado -
CARDINAL(S) = # of prime factors in s
você decompõe o número S que representa o conjunto em produto de fatores primos e adiciona seus expoentes. Caso o conjunto não permita duplicatas, você terá todos os expoentes 1.