Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't "values" property in a Dictionary a simple Array, but instead it's something weird?

let dict = [1:"One", 2:"Two", 3:"Three"]
let values = dict.values

print(values.dynamicType)

prints:

LazyMapCollection<Dictionary<Int, String>, String>

There are two things I don't understand here. Wouldn't it be a bit more simple if values returned an Array? Also, what is LazyMapCollection? I looked into Apple's reference but it provides literally no information (or nothing I am able to make sense of). You can iterate over this object, because it is CollectionType:

for v in values {
    print(v)
}

prints:

Two
Three
One

But for some reason Apple didn't use Array type.

like image 577
BR41N-FCK Avatar asked Nov 20 '15 10:11

BR41N-FCK


2 Answers

A LazyMapCollection is a lazy (only evaluated if necessary) view on a collection. By "view" I mean "window", "frame", "virtual subset", this kind of concept.

To get the actual values from it, just use the Array initializer:

let values = dict.values
let result = Array(values)
like image 61
Eric Aya Avatar answered Sep 30 '22 16:09

Eric Aya


You have here a serious speed optimisation. Creating an array is expensive. Instead you get an instance of some strange class that behaves in every way like an array. However, it doesn't have its data stored in a real array, instead it access the data from a dictionary.

Say you have a dictionary with 10,000 string values. You don't want iOS to copy all the 10,000 string values when you call dict.values, do you? That's what this class is there for, to prevent copying 10,000 strings. A real array would force copying.

And anyway, with your username you are asking for things like this, and Apple provides many examples. That's how they make iOS fast.

like image 20
gnasher729 Avatar answered Sep 30 '22 15:09

gnasher729