Conjunto rápido a matriz

187

Se NSSetpuede convertir a Arrayusando set.allObjects()pero no existe tal método en el nuevo Set(introducido con Swift 1.2). Todavía se puede hacer mediante la conversión de Swift Set a NSSet y usar el allObjects()método, pero eso no es óptimo.

Arroz frito
fuente

Respuestas:

352

Puede crear una matriz con todos los elementos de un Swift dado Setsimplemente con

let array = Array(someSet)

Esto funciona porque se Setajusta al SequenceTypeprotocolo y Arrayse puede inicializar con una secuencia. Ejemplo:

let mySet = Set(["a", "b", "a"])  // Set<String>
let myArray = Array(mySet)        // Array<String>
print(myArray) // [b, a]
Martin R
fuente
44
Como nota al margen, let array = Array(someSet)también funciona en Swift 2
Suragch
... o deje myArray = myNSSet.allObjects como! [mySpecificType]
angelos.p
3
@plusangel: Sí, si NSSetse da un. La pregunta era sobre un Swift Set.
Martin R
@KendallHelmstetterGelner: He verificado dos veces el ejemplo de código anterior con Swift 2.3 y Swift 3. Se compiló y funcionó como se esperaba para mí. ¿Qué error obtienes?
Martin R
@MartinR Interesante, lo estaba probando con un conjunto de una relación NSManagedObject, y no me gustó el constructor de Array en ese momento, ahora que intento reproducir el problema, no puedo. Sin embargo, tengo que agregar la etiqueta "arrayLiteral:" en el constructor de Array. Eliminé mi comentario anterior para no confundir a nadie, ¡gracias por revisar! No sé por qué la guía Swift no tiene esta forma de conversión ...
Kendall Helmstetter Gelner
21

En el caso más simple , con Swift 3, puede usar Arrayel init(_:)inicializador para obtener un Arrayde a Set. init(_:)tiene la siguiente declaración:

init<S>(_ s: S) where S : Sequence, Element == S.Iterator.Element

Crea una matriz que contiene los elementos de una secuencia.

Uso:

let stringSet = Set(arrayLiteral: "car", "boat", "car", "bike", "toy")    
let stringArray = Array(stringSet)

print(stringArray)
// may print ["toy", "car", "bike", "boat"]

Sin embargo , si también desea realizar algunas operaciones en cada elemento de su Settiempo transformándola en una Array, puede utilizar map, flatMap, sort, filtery otros métodos funcionales proporcionadas por Collectionel protocolo:

let stringSet = Set(["car", "boat", "bike", "toy"])
let stringArray = stringSet.sorted()

print(stringArray)
// will print ["bike", "boat", "car", "toy"]
let stringSet = Set(arrayLiteral: "car", "boat", "car", "bike", "toy") 
let stringArray = stringSet.filter { $0.characters.first != "b" }

print(stringArray)
// may print ["car", "toy"]
let intSet = Set([1, 3, 5, 2]) 
let stringArray = intSet.flatMap { String($0) }

print(stringArray)
// may print ["5", "2", "3", "1"]
let intSet = Set([1, 3, 5, 2])
// alternative to `let intArray = Array(intSet)`
let intArray = intSet.map { $0 }

print(intArray)
// may print [5, 2, 3, 1]
Imanou Petit
fuente
Usando uno de estos métodos, puedo hacer una matriz opcional a partir de un conjunto opcional.
tzaloga
11

ADICION:

Swift no tiene ORDEN DEFINIDO para Set y Dictionary. Por esa razón, debe usar el método sorted () para evitar obtener resultados inesperados, como su matriz puede ser como ["a", "b"] o ["b", "a "] y no quieres esto.

PARA ARREGLAR ESTO:

PARA CONJUNTOS

var example:Set = ["a","b","c"]
let makeExampleArray = [example.sorted()]
makeExampleArray 

Resultado: ["a", "b", "c"]

Sin ordenado ()

Puede ser:

["a","b","c"] or ["b","c","a",] or ["c","a","b"] or ["a","c","b"] or ["b","a","c"] or ["c","b","a"] 

matemática simple: 3! = 6


fuente
10

Creé una extensión simple que le da Arrayuna propiedad sin clasificar Seten Swift 4.0 .

extension Set {
    var array: [Element] {
        return Array(self)
    }
}

Si desea una matriz ordenada, puede agregar una propiedad computada adicional o modificar la existente para satisfacer sus necesidades.

Para usar esto, solo llame

let array = set.array
CodeBender
fuente
3

La respuesta actual para Swift 2.xy superior (de la guía del lenguaje de programación Swift sobre tipos de colección) parece ser iterar sobre las entradas de Set de la siguiente manera:

for item in myItemSet {
   ...
}

O, para usar el método "ordenado":

let itemsArray = myItemSet.sorted()

Parece que a los diseñadores de Swift no les gustaban todos los Objetos como mecanismo de acceso porque los Conjuntos no estaban realmente ordenados, por lo que querían asegurarse de que no salieran de una matriz sin un orden explícito aplicado.

Si no desea la sobrecarga de la clasificación y no le importa el orden, generalmente uso los métodos map o flatMap, que deberían ser un poco más rápidos para extraer una matriz:

let itemsArray = myItemSet.map { $0 }

Lo que generará una matriz del tipo que contiene el Conjunto, si necesita que sea una matriz de un tipo específico (por ejemplo, derechos de un conjunto de relaciones de objetos administrados que no se declaran como un conjunto escrito), puede hacer algo como:

var itemsArray : [MyObjectType] = []
if let typedSet = myItemSet as? Set<MyObjectType> {
 itemsArray = typedSet.map { $0 }
}
Kendall Helmstetter Gelner
fuente
myItemSet.sorted()requiere que los elementos sean Comparable. - myItemSet.map { $0 }debería producir el mismo resultado que Array(myItemSet), ambos crean una matriz enumerando todos los elementos del conjunto. Este último todavía funciona para mí, agradecería algunos detalles sobre su comentario anterior.
Martin R
-2

llama a este método y pasa tu set

func getArrayFromSet(set:NSSet)-> NSArray {

return set.map ({ String($0) })
}

Me gusta esto :

var letters:Set = Set<String>(arrayLiteral: "test","test") // your set
print(self.getArrayFromSet(letters))
Shubham bairagi
fuente
2
Usar matriz (<Set>) es una mejor opción
Sébastien REMY