Swift Set to Array


187

NSSetสามารถแปลงไปArrayใช้set.allObjects()แต่ไม่มีวิธีการดังกล่าวในใหม่Set(นำมาใช้กับสวิฟท์ 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คำถามคือเกี่ยวกับสวิฟท์
Martin R

@KendallHelmstetterGelner: ฉันได้ตรวจสอบซ้ำโค้ดตัวอย่างข้างต้นกับทั้ง Swift 2.3 และ Swift 3 มันรวบรวมและทำงานตามที่คาดไว้สำหรับฉัน คุณได้รับข้อผิดพลาดอะไร
Martin R

@ มาร์ตินน่าสนใจฉันลองใช้ชุดจากความสัมพันธ์ NSManagedObject และมันไม่ชอบตัวสร้าง Array ในเวลา - ตอนนี้ฉันพยายามทำซ้ำปัญหาแม้ว่าฉันไม่สามารถทำได้ ฉันต้องเพิ่มป้ายชื่อ "arrayLiteral:" ลงในตัวสร้าง Array ฉันลบความคิดเห็นก่อนหน้าของฉันดังนั้นจึงไม่ทำให้ใครสับสนขอบคุณสำหรับการตรวจสอบ! ผมไม่ทราบว่าทำไมคู่มือสวิฟท์ไม่ได้มีรูปแบบการแปลงนี้ ...
เคนดอล Helmstetter Gelner

21

ในกรณีที่ง่ายที่สุดกับสวิฟท์ 3 คุณสามารถใช้Array's init(_:)initializer ที่จะได้รับจากArray มีการประกาศดังต่อไปนี้:Setinit(_:)

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 ไม่มีคำสั่งซื้อที่กำหนดไว้สำหรับ Set และ Dictionary ด้วยเหตุนี้คุณควรใช้วิธี sort () เพื่อป้องกันการรับผลลัพธ์ที่ไม่คาดคิดเช่นอาร์เรย์ของคุณอาจเป็น ["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ในสวิฟท์ 4.0

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

ถ้าคุณต้องการอาร์เรย์ที่เรียงลำดับคุณสามารถเพิ่มคุณสมบัติที่คำนวณได้เพิ่มเติมหรือแก้ไขอาร์เรย์ที่มีอยู่เพื่อให้เหมาะกับความต้องการของคุณ

หากต้องการใช้สิ่งนี้เพียงโทร

let array = set.array

3

คำตอบปัจจุบันสำหรับ Swift 2.x และสูงกว่า (จากคำแนะนำการเขียนโปรแกรมภาษา Swift ในประเภทคอลเลกชัน) น่าจะเป็นการวนซ้ำในรายการ Set ดังนี้:

for item in myItemSet {
   ...
}

หรือเพื่อใช้วิธี "เรียงลำดับ":

let itemsArray = myItemSet.sorted()

ดูเหมือนว่านักออกแบบ Swift ไม่ชอบ allObjects เป็นกลไกการเข้าถึงเนื่องจากชุดไม่ได้รับคำสั่งจริงๆดังนั้นพวกเขาจึงต้องการให้แน่ใจว่าคุณไม่ได้ออกอาร์เรย์โดยไม่ต้องมีการสั่งซื้อที่ชัดเจน

หากคุณไม่ต้องการค่าใช้จ่ายในการเรียงลำดับและไม่สนใจเกี่ยวกับคำสั่งซื้อฉันมักจะใช้วิธีการ map หรือ flatMap ซึ่งควรจะเร็วกว่าเล็กน้อยในการแยกอาร์เรย์:

let itemsArray = myItemSet.map { $0 }

ซึ่งจะสร้างอาเรย์ประเภทที่ Set Set หากคุณต้องการให้เป็นอาเรย์ของประเภทเฉพาะ (พูด, entitles จากชุดของความสัมพันธ์ของออบเจ็กต์ที่มีการจัดการที่ไม่ได้ประกาศเป็นชุดที่พิมพ์) คุณสามารถทำสิ่งต่อไปนี้

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
Use Array (<Set>) เป็นตัวเลือกที่ดีกว่า
Sébastien REMY
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.