2015-03-14 2 views
116

NSSet может быть преобразован в Array с использованием set.allObjects(), но нет такого метода в новом Set (представленном Swift 1.2). Это можно сделать, преобразование Swift Set в NSSet и использование метода allObjects(), но это не оптимально.Swift Set to Array

ответ

225

Вы можете создать массив со всеми элементами из данного Swift Set просто с

let array = Array(someSet) 

Это работает, потому что Set соответствует SequenceType протоколу и Array может быть инициализирован с последовательностью. Пример:

let mySet = Set(["a", "b", "a"]) // Set<String> 
let myArray = Array(mySet)  // Array<String> 
print(myArray) // [b, a] 
+4

В качестве примечания, 'пусть массив = Array (someSet)' также работает в Swift 2 – Suragch

+0

... или пусть туАггау = myNSSet.allObjects, как! [mySpecificType] – plusangel

+2

@plusangel: Да, если задан 'NSSet'. Вопрос был о Swift 'Set'. –

-2

называют этот метод и передать ваш набор

func getArrayFromSet(set:NSSet)-> NSArray { 

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

Like This:

var letters:Set = Set<String>(arrayLiteral: "test","test") // your set 
print(self.getArrayFromSet(letters)) 
+2

Использование Array () - лучший выбор – iLandes

12

В простейшем случае с Swift 3, вы можете использовать Array «S init(_:) Инициализатор, чтобы получить Array от Set. init(_:) имеет следующую декларацию:

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

Создает массив, содержащий элементы последовательности.

Использование:

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

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

Однако, если вы хотите, чтобы выполнить некоторые операции по каждому элементу вашего Set при преобразовании его в Array, вы можете использовать map, flatMap, sort, filter и другие функциональные методы, предоставляемые протоколом Collection:

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] 
+0

Используя один из этих методов, я могу сделать дополнительный массив из дополнительного набора. – tzaloga

2

Текущий ответ для Swift 2.x и выше (от Swift языка программирования руководство по типам Collection), как представляется, либо перебрать Set такие как:

for item in myItemSet { 
    ... 
} 

Или, используйте «отсортированный» метод:

let itemsArray = myItemSet.sorted() 

Кажется, дизайнерам Swift не нравятся AllObjects как механизм доступа, поскольку наборы не очень упорядочены, так что они хотели, чтобы убедиться, что вы не вылезали массив без явного упорядочения.

Если вы не хотите, накладные расходы на сортировку и не заботиться о порядке, я обычно использую карту или методы flatMap, которые должны быть немного быстрее, чтобы извлечь массив:

let itemsArray = myItemSet.map { $0 } 

Какие построит массив типа Set, если вам нужно, чтобы он был массивом определенного типа (например, права на набор из отношений управляемых объектов, которые не объявлены как типизированные), вы можете сделать что-то вроде:

var itemsArray : [MyObjectType] = [] 
if let typedSet = myItemSet as? Set<MyObjectType> { 
itemsArray = typedSet.map { $0 } 
} 
+0

'myItemSet.sorted()' требует, чтобы элементы были 'Comparable'. - 'myItemSet.map {$ 0}' должен давать тот же результат, что и 'Array (myItemSet)', оба создают массив, перечисляя все элементы набора. Последний по-прежнему работает для меня, некоторые детали вашего вышеуказанного комментария будут оценены. –

7

ADDITION:

Swift не имеет DEFINED ORDER для набора и Dictionary.For, что причина, вы должны использовать отсортированы() метод, чтобы предотвратить получение неожиданных результатов, такие, как ваш массив может быть как [ «а», «б»] или ["b", "a"], и вы не хотите этого.

Чтобы это исправить:

для множеств

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

Результат: [ "а", "б", "в"]

Без сортировки()

Это может быть:

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

простой математика: 3! = 6

2

Я создал простое расширение, которое дает Вам несортированный Array как свойство Set в Swift 4,0.

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

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

Чтобы использовать эту функцию, просто вызовите

let array = set.array 
+1

@MartinR Спасибо, теперь не требуется, поэтому я обновил ответ – CodeBender