Swift Đặt thành Mảng


185

An NSSetcó thể được chuyển đổi sang Arraysử dụng set.allObjects()nhưng không có phương thức nào như vậy trong phần mới Set(được giới thiệu với Swift 1.2). Nó vẫn có thể được thực hiện bằng cách chuyển đổi Swift Set thành NSSet và sử dụng allObjects()phương thức nhưng điều đó không tối ưu.

Câu trả lời:


350

Bạn có thể tạo một mảng với tất cả các yếu tố từ một Swift nhất định Setchỉ bằng

let array = Array(someSet)

Điều này hoạt động vì Setphù hợp với SequenceTypegiao thức và Arraycó thể được khởi tạo với một chuỗi. Thí dụ:

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

4
Là một lưu ý phụ, let array = Array(someSet)cũng hoạt động trong Swift 2
Suragch

... hoặc để myArray = myNSSet.allObjects làm! [mySpecificType]
angelos.p

3
@plusangel: Có, nếu NSSetđược đưa ra. Câu hỏi là về một Swift Set.
Martin R

@KendallHelmstetterGelner: Tôi đã kiểm tra kỹ ví dụ mã trên với cả Swift 2.3 và Swift 3. Nó được biên dịch và hoạt động như mong đợi đối với tôi. lỗi gì bạn nhận được?
Martin R

@MartinR Thật thú vị, tôi đã thử nó với một tập hợp từ mối quan hệ NSManagedObject và nó không giống như trình xây dựng Array vào thời điểm đó - bây giờ tôi cố gắng tái tạo vấn đề mặc dù tôi không thể. Tôi phải thêm nhãn "ArrayLiteral:" vào hàm tạo Array. Tôi đã xóa nhận xét trước đây của mình để nó không gây nhầm lẫn cho bất kỳ ai, cảm ơn vì đã kiểm tra! Tôi không biết tại sao hướng dẫn Swift không có hình thức chuyển đổi này ...
Kendall Helmstetter Gelner

21

Trong trường hợp đơn giản nhất , với Swift 3, bạn có thể sử dụng Array's init(_:)initializer để có được một Arraytừ Set. init(_:)có tuyên bố sau:

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

Tạo một mảng chứa các phần tử của một chuỗi.

Sử dụng:

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

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

Tuy nhiên , nếu bạn cũng muốn thực hiện một số hoạt động trên mỗi phần tử của bạn Settrong khi biến nó thành một Array, bạn có thể sử dụng map, flatMap, sort, filtervà các phương pháp chức năng khác được cung cấp bởi Collectiongiao thức:

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]

Sử dụng một trong các phương pháp này tôi có thể tạo mảng tùy chọn từ bộ tùy chọn.
tzaloga

11

THÊM VÀO :

Swift không có thứ tự DEFINED cho Set và Dictionary. Vì lý do đó, bạn nên sử dụng phương thức sort () để tránh nhận kết quả không mong muốn như mảng của bạn có thể giống như ["a", "b"] hoặc ["b", "a "] Và bạn không muốn điều này.

ĐỂ CỐ ĐỊNH NÀY:

CHO TẬP HỢP

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

Kết quả: ["a", "b", "c"]

Không sắp xếp ()

Nó có thể:

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

toán đơn giản: 3! = 6


10

Tôi tạo ra một phần mở rộng đơn giản mà mang đến cho bạn một không được phân loại Arraynhư một tài sản của Settrong Swift 4.0 .

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

Nếu bạn muốn một mảng được sắp xếp, bạn có thể thêm một thuộc tính được tính toán bổ sung hoặc sửa đổi một thuộc tính hiện có cho phù hợp với nhu cầu của bạn.

Để sử dụng, chỉ cần gọi

let array = set.array

3

Câu trả lời hiện tại cho Swift 2.x trở lên (từ hướng dẫn Ngôn ngữ lập trình Swift về Loại bộ sưu tập) dường như lặp lại qua các mục nhập Set như vậy:

for item in myItemSet {
   ...
}

Hoặc, để sử dụng phương pháp "đã sắp xếp":

let itemsArray = myItemSet.sorted()

Có vẻ như các nhà thiết kế Swift không thích allObjects như một cơ chế truy cập vì Bộ thực sự không được đặt hàng, vì vậy họ muốn đảm bảo rằng bạn không nhận ra một mảng mà không áp dụng một thứ tự rõ ràng.

Nếu bạn không muốn chi phí phân loại và không quan tâm đến thứ tự, tôi thường sử dụng các phương pháp map hoặc FlatMap, nhanh hơn một chút để trích xuất một mảng:

let itemsArray = myItemSet.map { $0 }

Cái nào sẽ xây dựng một mảng kiểu mà Set giữ, nếu bạn cần nó là một mảng của một kiểu cụ thể (giả sử, phụ đề từ một tập hợp các quan hệ đối tượng được quản lý không được khai báo là một bộ gõ), bạn có thể làm một cái gì đó như:

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

myItemSet.sorted()đòi hỏi các yếu tố là Comparable. - myItemSet.map { $0 }sẽ tạo ra kết quả giống như Array(myItemSet), cả hai tạo ra một mảng bằng cách liệt kê tất cả các phần tử của tập hợp. Cái sau vẫn hoạt động với tôi, một số chi tiết về nhận xét trên của bạn sẽ được đánh giá cao.
Martin R

-2

gọi phương thức này và vượt qua tập của bạn

func getArrayFromSet(set:NSSet)-> NSArray {

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

Như thế này :

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

2
Sử dụng Mảng (<Set>) là lựa chọn tốt hơn
Sébastien REMY
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.