Jon_Hull
(Jon Hull)
1
I would really like to see something like the following added to the standard library:
extension Dictionary {
func mapValues<U>(transform:(Key,Value)->U)->[Key:U] {
var output:[Key:U] = [:]
for (k,v) in self {
output[k] = transform(k,v)
}
return output
}
}
It comes up enough that I have had to add it to pretty much every one of my projects. I also don’t feel comfortable adding it to my frameworks, since I figure a lot of people are also adding something like this to their projects, and I don’t want to cause a conflict with their version. Prime candidate for the standard library.
I like calling it ‘mapValues' as opposed to providing an override for map, since it makes the specific behavior more clear. I would expect ‘map' to possibly map the keys as well (though there are issues where the new keys overlap). I suppose you could just have a bunch of overrides for map if the compiler becomes good enough at differentiating return types: (Value)->(Value), (Key,Value)->Value, (Key, Value)->(Key,Value)
Thanks,
Jon
I would really like to see something like the following added to the standard library:
extension Dictionary {
func mapValues<U>(transform:(Key,Value)->U)->[Key:U] {
var output:[Key:U] = [:]
for (k,v) in self {
output[k] = transform(k,v)
}
return output
}
}
+1 from me, and +78 from people on Stack Overflow: <What's the cleanest way of applying map() to a dictionary in Swift? - Stack Overflow;
···
--
Brent Royal-Gordon
Architechies
“map” already "maps the values” so I think something like “transform” might be a little clearer, if we don’t want to just overload “map”. Regardless of what it’s called, though, I’m +1 on the functionality.
- Dave Sweeris
···
On Apr 13, 2016, at 1:41 AM, Jonathan Hull via swift-evolution <swift-evolution@swift.org> wrote:
I would really like to see something like the following added to the standard library:
extension Dictionary {
func mapValues<U>(transform:(Key,Value)->U)->[Key:U] {
var output:[Key:U] = [:]
for (k,v) in self {
output[k] = transform(k,v)
}
return output
}
}
It comes up enough that I have had to add it to pretty much every one of my projects. I also don’t feel comfortable adding it to my frameworks, since I figure a lot of people are also adding something like this to their projects, and I don’t want to cause a conflict with their version. Prime candidate for the standard library.
I like calling it ‘mapValues' as opposed to providing an override for map, since it makes the specific behavior more clear. I would expect ‘map' to possibly map the keys as well (though there are issues where the new keys overlap). I suppose you could just have a bunch of overrides for map if the compiler becomes good enough at differentiating return types: (Value)->(Value), (Key,Value)->Value, (Key, Value)->(Key,Value)
Thanks,
Jon
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
dabrahams
(Dave Abrahams)
4
I agree that we need a way to do this, and was surprised when what I
tried didn't work. This should work:
Dictionary(d.lazy.map { (k, v) in (k, transform(v)) })
We should have a proposal that makes the constructor work* if we don't
already have one.
I'm inclined against building specialized variants of basic algorithms
into particular collections, though. Could be talked out of it if the
use-case is strong enough.
···
on Tue Apr 12 2016, Jonathan Hull <swift-evolution@swift.org> wrote:
I would really like to see something like the following added to the standard
library:
extension Dictionary {
func mapValues<U>(transform:(Key,Value)->U)->[Key:U] {
var output:[Key:U] = [:]
for (k,v) in self {
output[k] = transform(k,v)
}
return output
}
}
It comes up enough that I have had to add it to pretty much every one of my
projects. I also don’t feel comfortable adding it to my frameworks, since I
figure a lot of people are also adding something like this to their projects,
and I don’t want to cause a conflict with their version. Prime candidate for the
standard library.
I like calling it ‘mapValues' as opposed to providing an override for map, since
it makes the specific behavior more clear. I would expect ‘map' to possibly map
the keys as well (though there are issues where the new keys overlap). I suppose
you could just have a bunch of overrides for map if the compiler becomes good
enough at differentiating return types: (Value)->(Value), (Key,Value)->Value,
(Key, Value)->(Key,Value)
------
* Only question: does this need a label, e.g.
Dictionary(uniquingKeys: d.lazy.map { (k, v) in (k, transform(v)) })
to denote that it's lossy?
--
Dave
VladimirS
(Vladimir)
5
+1 for this. Highly useful method and imo should be implemented for Dictionary.
And what if we need to transform the key?
For ex. we have
var d = ["1" : "abc", "2" : "def"]
we could have such method:
d.mapKeys {k,v -> Int in Int(k)! }
to get:
[2: "abc", 1: "def"]
I.e. I suggest to implement and mapKeys() also. It could be also useful in some situations.
···
On 13.04.2016 9:41, Jonathan Hull via swift-evolution wrote:
I would really like to see something like the following added to the
standard library:
extensionDictionary{
func mapValues<U>(transform:(Key,Value)->U)->[Key:U] {
var output:[Key:U] = [:]
for (k,v) in self {
output[k] = transform(k,v)
}
return output
}
}
It comes up enough that I have had to add it to pretty much every one of my
projects. I also don’t feel comfortable adding it to my frameworks, since
I figure a lot of people are also adding something like this to their
projects, and I don’t want to cause a conflict with their version. Prime
candidate for the standard library.
I like calling it ‘mapValues' as opposed to providing an override for map,
since it makes the specific behavior more clear. I would expect ‘map' to
possibly map the keys as well (though there are issues where the new keys
overlap). I suppose you could just have a bunch of overrides for map if
the compiler becomes good enough at differentiating return types:
(Value)->(Value), (Key,Value)->Value, (Key, Value)->(Key,Value)
Thanks,
Jon
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
Qbyte
6
I like the idea of having a mapping method which maps back to the actual type.
What about a more general approach? consider:
mappedSelf(transform: T -> U) -> Self<U>
filteredSelf(includeElement: T -> Bool) -> Self<U>
Which can be added to other collections like Set and sequences like a lazy number sequence.
Best regards
- Maximilian
···
Am 13.04.2016 um 08:41 schrieb Jonathan Hull via swift-evolution <swift-evolution@swift.org>:
I would really like to see something like the following added to the standard library:
extension Dictionary {
func mapValues<U>(transform:(Key,Value)->U)->[Key:U] {
var output:[Key:U] = [:]
for (k,v) in self {
output[k] = transform(k,v)
}
return output
}
}
It comes up enough that I have had to add it to pretty much every one of my projects. I also don’t feel comfortable adding it to my frameworks, since I figure a lot of people are also adding something like this to their projects, and I don’t want to cause a conflict with their version. Prime candidate for the standard library.
I like calling it ‘mapValues' as opposed to providing an override for map, since it makes the specific behavior more clear. I would expect ‘map' to possibly map the keys as well (though there are issues where the new keys overlap). I suppose you could just have a bunch of overrides for map if the compiler becomes good enough at differentiating return types: (Value)->(Value), (Key,Value)->Value, (Key, Value)->(Key,Value)
Thanks,
Jon
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
I.e. I suggest to implement and mapKeys() also. It could be also useful in some situations.
`mapKeys` is much more dangerous, because you could end up mapping many values into a single key. You kind of need to combine the values somehow. Perhaps:
extension Dictionary {
func mapValues<OutValue>(_ valueTransform: @noescape Value throws -> OutValue) rethrows -> [Key: OutValue] { … }
func mapKeys<OutKey: Hashable>(_ keyTransform: @noescape Key throws -> OutKey) rethrows -> [OutKey: [Value]] { … }
// Possibly flatMap variants, too?
}
extension Dictionary where Value: Sequence {
func reduceValues<OutValue>(_ initial: OutValue, combine: @noescape (OutValue, Value.Iterator.Element) throws -> OutValue) rethrows -> [Key: OutValue] {
return mapValues { $0.reduce(initial, combine: combine) }
}
}
Which you would end up using like this:
let wordFrequencies: [String: Int] = …
let firstLetterFrequencies: [Character: Int] = wordFrequencies.mapKeys { $0.characters.first! }.reduceValues(0, combine: +)
···
--
Brent Royal-Gordon
Architechies