Swift Dictionary: Get values as array

ArraysDictionarySwift

Arrays Problem Overview


I have a dictionary containing UIColor objects hashed by an enum value, ColorScheme:

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

I would like to be able to extract an array of all the colors (the values) contained by this dictionary. I thought I could use the values property, as is used when iterating over dictionary values (for value in dictionary.values {...}), but this returns an error:

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

It seems that rather than returning an Array of values, the values method returns a more abstract collection type. Is there a way to get an Array containing the dictionary's values without extracting them in a for-in loop?

Arrays Solutions


Solution 1 - Arrays

As of Swift 2.0, Dictionary’s values property now returns a LazyMapCollection instead of a LazyBidirectionalCollection. The Array type knows how to initialise itself using this abstract collection type:

let colors = Array(colorsForColorSchemes.values)

Swift's type inference already knows that these values are UIColor objects, so no type casting is required, which is nice!

Solution 2 - Arrays

You can map dictionary to an array of values:

let colors = colorsForColorScheme.map { $0.1 }

Closure takes a key-value tuple from dictionary and returns just a value. So, map function produces an array of values.

More readable version of the same code:

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

UPDATE

From Xcode 9.0, dictionary values can be accessed using values property, which conforms to Collection protocol:

let colors = colorsForColorScheme.values

Typically you just want it as an array:

let colors = Array(dict.values)

and that's it.

Solution 3 - Arrays

Use colorsForColorScheme.map({$0.value})

Solution 4 - Arrays

you can create an extension on LazyMapCollection

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

colorsForColorSchemes.values.toArray() or colorsForColorSchemes.keys.toArray()

Solution 5 - Arrays

Firstly, from the following statement, it seems that your variable(dictionary) name is colorsForColorScheme

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

while you are trying to get the values from colorsForColorSchemes dictionary when you did-

let colors: [UIColor] = colorsForColorSchemes.values

which should give you a compile time error. Anyways I am assuming that you had a typo, and you dictionary's name is colorsForColorSchemes. So, here is the solution-

As mentioned earlier, because of the type inference property in swift, your code can infer that the returned type from the .values function is returning an array of UIColor. However, Swift wants to be type-safe, so when you store the values in the colors array, you need to explicitly define that. For swift 5 and above, now you could just do following-

let colors = [UIColor](colorsForColorSchemes.values)

Solution 6 - Arrays

You can also use flatMap:

let colors = colorsForColorScheme.values.flatMap { $0 }

Solution 7 - Arrays

I've found this to be the most useful in Swift 5:

colorsForColorSchemes.allValues

See docs - https://developer.apple.com/documentation/foundation/nsdictionary/1408915-allvalues

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStuartView Question on Stackoverflow
Solution 1 - ArraysStuartView Answer on Stackoverflow
Solution 2 - ArrayspjuzeliunasView Answer on Stackoverflow
Solution 3 - ArraysVishal kundaliyaView Answer on Stackoverflow
Solution 4 - ArraysGSerjoView Answer on Stackoverflow
Solution 5 - ArraysNatashaView Answer on Stackoverflow
Solution 6 - ArrayskrlbskView Answer on Stackoverflow
Solution 7 - ArraysandrewlundyView Answer on Stackoverflow