[swift-evolution] map-like operation that returns a dictionary

Kenny Leung kenny_leung at pobox.com
Wed Jan 13 10:26:43 CST 2016


Hmm…

Now that I look seriously at it, I have no idea how the first function works! Back to the books…

-Kenny


> On Jan 12, 2016, at 10:11 AM, Thorsten Seitz <tseitz42 at icloud.com> wrote:
> 
> struct Person {
>     var id: Int
>     var name: String
> }
> let tom   = Person(id: 1, name: "Tom")
> let dick  = Person(id: 2, name: "Dick")
> let harry = Person(id: 3, name: "Harry")
> let people = [tom, dick, harry]
> 
> extension SequenceType {
>     
>     func toDict<Key: Hashable>(@noescape withKey extractKey: Self.Generator.Element -> Key) 
> 	-> [Key:Self.Generator.Element]
>     {
>         return toDict { element in (extractKey(element), element) }
>     }
>     
>     func toDict<Key: Hashable, Value>(@noescape mapping: Self.Generator.Element -> (Key, Value))
>         -> [Key:Value]
>     {
>         var result: [Key:Value] = [:]
>         for element in self {
>             let (key, value) = mapping(element)
>             result.updateValue(value, forKey: key)
>         }
>         return result
>     }
> }
> 
> let cache = people.toDict { $0.id }
> cache
> 
> I named the method(s) „toDict“ instead of „map“ because map normally returns a collection which is either the same as the receiver or a simple one.
> The second version is more general and allows to do things like
> 
> let dict = ["Tom", "Dick", "Harry"].enumerate().toDict { (index, value) in (index + 1, value) }
> 
> 
> -Thorsten
> 
> 
>> Am 11.01.2016 um 17:56 schrieb Kenny Leung via swift-evolution <swift-evolution at swift.org>:
>> 
>> I would like to keep this lightweight for the consumer, so you could write:
>> 
>> let people :[Person] = fetchPeople()
>> let cache :[Int:Person] = people.map {return $0.id}
>> 
>> -Kenny
>> 
>> 
>>> On Jan 10, 2016, at 2:24 PM, Jo Albright via swift-evolution <swift-evolution at swift.org> wrote:
>>> 
>>> Possible solution to do what you are wanting. 
>>> 
>>> extension Array {
>>> 
>>>    func map<T>(var d: [String:T] = [:], @noescape transform: (Int,Array.Generator.Element) throws -> [String:T]) rethrows -> [String:T] {
>>> 
>>>        for (i,item) in self.enumerate() {
>>> 
>>>            try d += transform(i,item)
>>> 
>>>        }
>>> 
>>>        return d
>>> 
>>>    }
>>> 
>>> }
>>> 
>>> func += <T>(inout lhs: [String:T], rhs: [String:T]) -> [String:T] {
>>> 
>>>    for (k,v) in rhs { lhs[k] = v }; return lhs
>>> 
>>> }
>>> 
>>> 
>>> let names = ["Jo","Jenna","Jake","Julie"]
>>> let ages = [32,20,46,39]
>>> 
>>> let namesInfo1 = names.map { ["\($0)": $1] }
>>> namesInfo1 // ["2": "Jake", "1": "Jenna", "0": "Jo", "3": "Julie"]
>>> 
>>> let namesInfo2 = names.map(["6":"Jim"]) { ["\($0)": $1] }
>>> namesInfo2 // ["2": "Jake", "1": "Jenna", "0": "Jo", "6": "Jim", "3": "Julie"]
>>> 
>>> let namesInfo3 = names.map { [$1: ages[$0]] }
>>> namesInfo3 // ["Jenna": 20, "Jo": 32, "Jake": 46, "Julie": 39]
>>> 
>>> Designer . Developer .  Nerd 
>>> Jo Albright
>>> 
>>> 
>>>> On Jan 10, 2016, at 4:25 PM, Loïc Lecrenier via swift-evolution <swift-evolution at swift.org> wrote:
>>>> 
>>>> I think this is O(n^2) though, so it’s not really usable.
>>>> (It is destroying and copying the dictionary each time)
>>>> 
>>>> There really isn’t anything like map for dictionaries. 
>>>> I am not convinced we should add it to the standard library though.
>>>> 
>>>>> On Jan 10, 2016, at 10:19 PM, Ian Ynda-Hummel via swift-evolution <swift-evolution at swift.org> wrote:
>>>>> 
>>>>> I think this probably wants to be a `reduce`. Given the above example:
>>>>> 
>>>>>   ["John", "Mike", "Amy", "Kavin"].enumerate().reduce([Int: String]()) { (var dictionary, data) in
>>>>>       dictionary[data.index] = data.element
>>>>>       return dictionary
>>>>>   }
>>>>> 
>>>>> Which means you create an immutable dictionary with `let`. This could probably look nicer, but I think it illustrates the idea, at least.
>>>>> 
>>>>> -Ian
>>>>> 
>>>>> On Sun, Jan 10, 2016 at 2:46 PM Craig Cruden via swift-evolution <swift-evolution at swift.org> wrote:
>>>>> There is no equivalent to something like 
>>>>> 
>>>>> array.zipWithIndex.toMap (or in this case array.zipWithIndex.toDictionary // where zipWithIndex creates tuples with the index - a specialized case of zip for Arrays with indexes.
>>>>> 
>>>>> 
>>>>> 
>>>>>> On 2016-01-11, at 2:41:59, Ross O'Brien via swift-evolution <swift-evolution at swift.org> wrote:
>>>>>> 
>>>>>> Or an enumeration followed by a forEach.
>>>>>> ["John", "Mike", "Amy", Kavin"].enumerate().forEach {
>>>>>>   dic[$0] = $1
>>>>>> }
>>>>>> That said, it requires creating a dictionary var first, not a let. If there was an initialiser for Dictionary which took an Array or EnumerateSequence, that might be useful. I'm not sure how I'd attempt to write such an initialiser though.
>>>>>> 
>>>>>> 
>>>>>> On Sun, Jan 10, 2016 at 7:08 PM, Donnacha Oisín Kidney <swift-evolution at swift.org> wrote:
>>>>>> I think that use of map is generally discouraged. forEach would probably be more explicit, or a for-loop.
>>>>>> 
>>>>>>> On 10 Jan 2016, at 18:58, 肇鑫 via swift-evolution <swift-evolution at swift.org> wrote:
>>>>>>> 
>>>>>>> You can use dictionary in a map. You just ignore the return value of the map.
>>>>>>> 
>>>>>>> var dic = [Int:String]()
>>>>>>> var index = 0
>>>>>>> 
>>>>>>> ["John", "Mike", "Amy", "Kavin"].map {
>>>>>>>   dic.updateValue($0, forKey: index)
>>>>>>>   index += 1
>>>>>>> }
>>>>>>> 
>>>>>>> print(dic) // [2: "Amy", 0: "John", 1: "Mike", 3: "Kavin"]
>>>>>>> 
>>>>>>> zhaoxin
>>>>>>> 
>>>>>>> On Mon, Jan 11, 2016 at 1:50 AM, Kenny Leung via swift-evolution <swift-evolution at swift.org> wrote:
>>>>>>> Hi All.
>>>>>>> 
>>>>>>> I find that instead of using map() on arrays, I more often use an operation that returns a dictionary from an array. A common case is fetching an array of data, then creating a local cache of it indexed by ID.
>>>>>>> 
>>>>>>> Is there a name for this operation? Is this something that others would like to see added to the standard library?
>>>>>>> 
>>>>>>> -Kenny
>>>>>>> 
>>>>>>> _______________________________________________
>>>>>>> swift-evolution mailing list
>>>>>>> swift-evolution at swift.org
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> -- 
>>>>>>> 
>>>>>>> Owen Zhao
>>>>>>> _______________________________________________
>>>>>>> swift-evolution mailing list
>>>>>>> swift-evolution at swift.org
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> _______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> swift-evolution at swift.org
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>> 
>>>>>> 
>>>>>> _______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> swift-evolution at swift.org
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>> 
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 



More information about the swift-evolution mailing list