Swift Dictionary: Lấy giá trị dưới dạng mảng


150

Tôi có một từ điển chứa UIColorcác đối tượng được băm bởi một giá trị enum , ColorScheme:

var colorsForColorScheme: [ColorScheme : UIColor] = ...

Tôi muốn có thể trích xuất một mảng của tất cả các màu (các giá trị) có trong từ điển này. Tôi nghĩ rằng tôi có thể sử dụng thuộc valuestính, như được sử dụng khi lặp qua các giá trị từ điển ( for value in dictionary.values {...}), nhưng điều này trả về một lỗi:

let colors: [UIColor] = colorsForColorSchemes.values
                        ~~~~~~~~~~~~~~~~~~~~~^~~~~~~
'LazyBidrectionalCollection<MapCollectionView<Dictionary<ColorScheme, UIColor>, UIColor>>' is not convertible to 'UIColor'

Có vẻ như thay vì trả về một Arraygiá trị, valuesphương thức trả về kiểu bộ sưu tập trừu tượng hơn. Có cách nào để có được một Arraygiá trị chứa từ điển mà không cần trích xuất chúng trong một for-invòng lặp không?


1
Swift 5: colorsForColorSchemes.values
Juan Boero

Câu trả lời:


284

Tính đến Swift 2.0, Dictionarycủa valuesbất động sản hiện nay trả về một LazyMapCollectionthay vì một LazyBidirectionalCollection. Các Arrayloại biết làm thế nào để khởi bản thân sử dụng loại bộ sưu tập trừu tượng này:

let colors = Array(colorsForColorSchemes.values)

Suy luận kiểu của Swift đã biết rằng các giá trị này là UIColorcác đối tượng, do đó không cần truyền kiểu, điều này thật tuyệt!


1
bạn cũng có thể sử dụng nó như là một mảng với các đối tượng được gõ. làm việc tuyệt vời cảm ơn let colors = [CustomColorObject] (colorsForColorScheme.values)
bolnad

6
Có vẻ như trong Swift 2.0, Dictionary.values ​​hiện trả về LazyMapCollection trái ngược với LazyBidirectionalCollection. Thật không may, .array không được xác định trên LazyMapCollection. Tuy nhiên, cách Array (dictionary.values) vẫn hoạt động tốt vì các kiểu mảng biết cách tự khởi tạo từ LazyMapCollection.
Tod Cickyham

8
Xin lưu ý rằng thứ tự của các giá trị có thể là bất ngờ. Ví dụ [0: "small", 1: "medium", 2: "large"]có thể sẽ KHÔNG tạo ra["small", "medium", "large"]
Simon Bengtsson

55

Bạn có thể ánh xạ từ điển tới một mảng các giá trị:

let colors = colorsForColorScheme.map { $0.1 }

Việc đóng lấy một bộ giá trị khóa từ từ điển và chỉ trả về một giá trị. Vì vậy, hàm map tạo ra một mảng các giá trị.

Phiên bản dễ đọc hơn của cùng một mã:

let colors = colorsForColorScheme.map { (scheme, color) in
    return color
}

CẬP NHẬT

Từ Xcode 9.0, các giá trị từ điển có thể được truy cập bằng thuộc valuestính, phù hợp với Collectiongiao thức:

let colors = colorsForColorScheme.values

Thông thường bạn chỉ muốn nó như một mảng:

let colors = Array(dict.values)

và đó là nó.


2
Nhưng thực ra đây là cách dễ đọc để lấy mảng let colors = Array (colorsForColorScheme.values)
Renetik

1
thích giải pháp này
Navy Seal

@pjuzeliunas vì đây là câu trả lời tốt nhất ở đây, tôi chỉ chỉnh sửa mới nhất cho năm 2020. rõ ràng là thư giãn, chỉnh sửa vv! chúc mừng và cảm ơn!
Fattie


8

bạn có thể tạo một phần mở rộng trên LazyMapCollection

public extension LazyMapCollection  {

    func toArray() -> [Element]{
        return Array(self)
    }
}

colorsForColorSchemes.values.toArray() hoặc là colorsForColorSchemes.keys.toArray()


3

Thứ nhất, từ câu lệnh sau, có vẻ như tên biến (từ điển) của bạn là colorsForColorScheme

var colorsForColorScheme: [ColorScheme : UIColor] = ... 

trong khi bạn đang cố gắng để có được các giá trị từ từ colorsForColorSchemesđiển khi bạn đã làm-

let colors: [UIColor] = colorsForColorSchemes.values

mà sẽ cung cấp cho bạn một lỗi thời gian biên dịch. Dù sao, tôi giả sử rằng bạn có một lỗi đánh máy, và tên của bạn là từ điển colorsForColorSchemes. Vì vậy, đây là giải pháp-

Như đã đề cập trước đó, do thuộc tính suy luận kiểu trong swift, mã của bạn có thể suy ra rằng kiểu được trả về từ .valueshàm đang trả về một mảng UIColor. Tuy nhiên, Swift muốn an toàn kiểu, vì vậy khi bạn lưu trữ các giá trị trong colorsmảng, bạn cần xác định rõ ràng điều đó. Đối với swift 5 trở lên, bây giờ bạn có thể thực hiện theo-

let colors = [UIColor](colorsForColorSchemes.values)

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.