Swift Встановити масив


187

Перехід NSSetможе бути перетворений на Arrayвикористання, set.allObjects()але в новому такому методі немає Set(введено Swift 1.2). Це все ще можна зробити, перетворивши Swift Set в NSSet і скориставшись allObjects()методом, але це не є оптимальним.

Відповіді:


352

Ви можете створити масив з усіма елементами з даного 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
Як зауваження, let array = Array(someSet)також працює у Swift 2
Suragch

... або нехай myArray = myNSSet.allObjects як! [mySpecificType]
angelos.p

3
@plusangel: Так, якщо NSSetвказано. Питання стосувалося Швидкого Set.
Мартін Р

@KendallHelmstetterGelner: Я двічі перевірив наведений вище приклад коду як із Swift 2.3, так і з Swift 3. Він склав і працював так, як очікувалося для мене. Яку помилку ви отримаєте?
Мартін Р

@MartinR Цікаво, що я пробував це з набором відносин NSManagedObject, і це не сподобалось конструктору Array на той час - тепер, коли я намагаюся відтворити проблему, я не можу. Мені потрібно додати мітку "arrayLiteral:" в конструктор Array. Я видалив попередній коментар, щоб він нікого не бентежив, дякую за перевірку! Я не знаю, чому в посібнику Свіфт немає такої форми перетворення ...
Кендалл Гельмстерт Гельнер,

21

У найпростішому випадку , за допомогою 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]

Використовуючи один із цих методів, я можу зробити необов'язковий масив із необов'язкового набору.
tzaloga

11

ДОПОМОГА:

У Swift немає ВИЗНАЧЕНОГО ЗАМОВЛЕННЯ для набору та словника. З цієї причини вам слід використовувати метод sorted (), щоб запобігти отриманню несподіваних результатів, таких як ваш масив, може бути як ["a", "b"] або ["b", "a "] і ти цього не хочеш.

ВИРІШИТИ ЦЕ:

ДЛЯ НАСТРОЙКІВ

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

Результат: ["a", "b", "c"]

Без сортування ()

Це може бути:

["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


10

Я створив просте розширення, яке дає вам несортоване Arrayяк властивість Setу Swift 4.0 .

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

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

Щоб скористатися цим, просто зателефонуйте

let array = set.array

3

Поточна відповідь для Swift 2.x та вище (з посібника з мови програмування Swift щодо типів колекції), здається, чи то повторює такі налаштування:

for item in myItemSet {
   ...
}

Або використовувати "відсортований" метод:

let itemsArray = myItemSet.sorted()

Здається, дизайнерам Swift не сподобалося allObjects як механізм доступу, оскільки набори насправді не впорядковані, тому вони хотіли переконатися, що ви не вибрали масив без явного замовлення.

Якщо ви не хочете, щоб набір сортування і не піклувався про порядок, я зазвичай використовую методи map або flatMap, які повинні бути трохи швидшими для отримання масиву:

let itemsArray = myItemSet.map { $0 }

Який буде створювати масив типу, який має набір, якщо вам потрібен масив певного типу (скажімо, має право набір керованих об'єктних відносин, які не оголошені як набраний набір), ви можете зробити щось на кшталт:

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

myItemSet.sorted()вимагає, щоб елементи були Comparable. - myItemSet.map { $0 }повинен дати той самий результат Array(myItemSet), що і обидва створити масив, перерахувавши всі елементи набору. Останній все ще працює для мене, деякі деталі щодо вашого вище коментаря були б вдячні.
Martin R

-2

зателефонуйте цьому методу та передайте свій набір

func getArrayFromSet(set:NSSet)-> NSArray {

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

Подобається це :

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

2
Використовувати масив (<Set>) - кращий вибір
Sébastien REMY
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.