พจนานุกรม Swift: รับค่าเป็นอาร์เรย์


151

ฉันมีพจนานุกรมที่มีUIColorวัตถุที่แฮชโดยค่า enum ColorScheme:

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

ฉันต้องการแยกอาเรย์ของสีทั้งหมด (ค่า) ที่อยู่ในพจนานุกรมนี้ ฉันคิดว่าฉันสามารถใช้valuesคุณสมบัติได้ตามที่ใช้เมื่อทำการวนซ้ำค่าพจนานุกรม ( for value in dictionary.values {...}) แต่สิ่งนี้ส่งกลับข้อผิดพลาด:

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

ดูเหมือนว่าแทนที่จะส่งคืนArrayค่าของvaluesวิธีการส่งกลับประเภทคอลเลกชันที่เป็นนามธรรมมากขึ้น มีวิธีการรับArrayค่าของพจนานุกรมโดยไม่แยกในfor-inวนหรือไม่


1
Swift 5: colorsForColorSchemes.values
Juan Boero

คำตอบ:


285

ในฐานะของสวิฟท์ 2.0 Dictionaryของvaluesสถานที่ให้บริการในขณะนี้ส่งกลับแทนLazyMapCollection ประเภทรู้วิธีที่จะ initialise ตัวเองใช้ประเภทคอลเลกชันนี้เป็นนามธรรม:LazyBidirectionalCollectionArray

let colors = Array(colorsForColorSchemes.values)

การอนุมานประเภทของ Swift รู้อยู่แล้วว่าค่าเหล่านี้เป็นUIColorวัตถุดังนั้นจึงไม่จำเป็นต้องใช้การหล่อแบบ


1
นอกจากนี้คุณยังสามารถโยนมันเป็นอาร์เรย์ที่มีวัตถุที่พิมพ์ได้เช่นกัน ใช้งานได้ดี! ขอบคุณให้สี = [CustomColorObject] (colorsForColorSchemes.values)
bolnad

6
ดูเหมือนว่าใน Swift 2.0 ตอนนี้ Dictionary.values ​​จะส่งคืน LazyMapCollection ซึ่งตรงข้ามกับ LazyBidirectionalCollection ขออภัย. array ไม่ได้ถูกกำหนดไว้ใน LazyMapCollection อย่างไรก็ตามวิธี Array (dictionary.values) ยังคงทำงานได้ดีเนื่องจากประเภทอาร์เรย์รู้วิธีเริ่มต้นตัวเองจาก LazyMapCollection
Tod Cunningham

8
โปรดทราบว่าลำดับของค่าอาจไม่คาดคิด ตัวอย่างเช่น[0: "small", 1: "medium", 2: "large"]อาจจะไม่สร้าง["small", "medium", "large"]
Simon Bengtsson

55

คุณสามารถแมปพจนานุกรมเข้ากับอาร์เรย์ของค่าต่างๆ:

let colors = colorsForColorScheme.map { $0.1 }

การปิดจะใช้ tuple คีย์ - ค่าจากพจนานุกรมและส่งคืนค่า ดังนั้นฟังก์ชั่นแผนที่สร้างอาร์เรย์ของค่า

รุ่นเดียวกันอ่านเพิ่มเติมของรหัสเดียวกัน:

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

UPDATE

จาก Xcode 9.0 ค่าพจนานุกรมสามารถเข้าถึงได้โดยใช้valuesคุณสมบัติซึ่งสอดคล้องกับCollectionโปรโตคอล:

let colors = colorsForColorScheme.values

โดยทั่วไปแล้วคุณต้องการให้มันเป็นอาร์เรย์:

let colors = Array(dict.values)

และนั่นคือมัน


2
แต่อันที่จริงนี่เป็นวิธีที่อ่านได้เพื่อให้ array ให้สี = Array (colorsForColorScheme.values)
Renetik

1
รักวิธีแก้ปัญหานี้
Navy Seal

@pjuzeliunas เนื่องจากนี่เป็นคำตอบที่ดีที่สุดที่นี่ฉันเพิ่งแก้ไขในปี 2020 เห็นได้ชัดว่าผ่อนคลายแก้ไข ฯลฯ ! ไชโยและขอบคุณ!
Fattie


8

คุณสามารถสร้างส่วนขยายได้ LazyMapCollection

public extension LazyMapCollection  {

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

colorsForColorSchemes.values.toArray() หรือ colorsForColorSchemes.keys.toArray()


3

ประการแรกจากคำสั่งต่อไปนี้ดูเหมือนว่าชื่อตัวแปร (พจนานุกรม) ของคุณคือ colorsForColorScheme

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

ในขณะที่คุณพยายามรับค่าจากcolorsForColorSchemesพจนานุกรมเมื่อคุณ -

let colors: [UIColor] = colorsForColorSchemes.values

ซึ่งควรให้ข้อผิดพลาดเวลารวบรวม อย่างไรก็ตามฉันสมมติว่าคุณมีตัวพิมพ์ผิดและชื่อพจนานุกรมของคุณคือcolorsForColorSchemesฉันสมมติว่าคุณมีการพิมพ์ผิดและคุณพจนานุกรมชื่อเป็น ดังนั้นนี่คือทางออก -

ดังที่ได้กล่าวไว้ก่อนหน้านี้เนื่องจากคุณสมบัติการอนุมานชนิดอย่างรวดเร็วรหัสของคุณสามารถอนุมานได้ว่าชนิดที่ส่งคืนจาก.valuesฟังก์ชันส่งคืนอาร์เรย์ของ UIColor อย่างไรก็ตาม Swift ต้องการที่จะเป็นประเภทที่ปลอดภัยดังนั้นเมื่อคุณเก็บค่าในcolorsอาร์เรย์คุณจะต้องกำหนดอย่างชัดเจน สำหรับ swift 5 ขึ้นไปตอนนี้คุณสามารถทำตามได้ -

let colors = [UIColor](colorsForColorSchemes.values)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.