Merge pull request #83429 from CrazyFanFan/feature/cxx_map_mapvalues_and_compactmapvalues

Adds `mapValues` and `compactMapValues` to CxxDictionary:
This commit is contained in:
Egor Zhdan
2025-10-13 12:00:57 +01:00
committed by GitHub
3 changed files with 135 additions and 0 deletions

View File

@@ -144,6 +144,60 @@ extension CxxDictionary {
}
}
@inlinable
public func mapValues<R, E>(
_ transform: (Value) throws(E) -> R.Value
) throws(E) -> R where R: CxxDictionary, R.Key == Key {
var result = R.init()
var iterator = __beginUnsafe()
let endIterator = __endUnsafe()
while iterator != endIterator {
let pair = iterator.pointee
try result.__insertUnsafe(R.Element(first: pair.first, second: transform(pair.second)))
iterator = iterator.successor()
}
return result
}
@inlinable
@_disfavoredOverload
public func mapValues<E>(
_ transform: (Value) throws(E) -> Value
) throws(E) -> Self {
return try mapValues(transform) as Self
}
@inlinable
public func compactMapValues<R, E>(
_ transform: (Value) throws(E) -> R.Value?
) throws(E) -> R where R: CxxDictionary, R.Key == Key {
var result = R.init()
var iterator = __beginUnsafe()
let endIterator = __endUnsafe()
while iterator != endIterator {
let pair = iterator.pointee
if let value = try transform(pair.second) {
result.__insertUnsafe(R.Element(first: pair.first, second: value))
}
iterator = iterator.successor()
}
return result
}
@inlinable
@_disfavoredOverload
public func compactMapValues<E>(
_ transform: (Value) throws(E) -> Value?
) throws(E) -> Self {
return try compactMapValues(transform) as Self
}
public func filter(_ isIncluded: (_ key: Key, _ value: Value) throws -> Bool) rethrows -> Self {
var filteredDictionary = Self.init()
var iterator = __beginUnsafe()

View File

@@ -10,8 +10,10 @@ using Map = std::map<int, int>;
using MapStrings = std::map<std::string, std::string>;
using NestedMap = std::map<int, Map>;
using MapGroup = std::map<int, std::vector<int>>;
using MapIntString = std::map<int, std::string>;
using UnorderedMap = std::unordered_map<int, int>;
using UnorderedMapGroup = std::unordered_map<int, std::vector<int>>;
using UnorderedIntString = std::unordered_map<int, std::string>;
inline Map initMap() { return {{1, 3}, {2, 2}, {3, 3}}; }
inline UnorderedMap initUnorderedMap() { return {{1, 3}, {3, 3}, {2, 2}}; }
inline Map initEmptyMap() { return {}; }

View File

@@ -304,6 +304,85 @@ StdMapTestSuite.test("UnorderedMap.subscript(:default:)") {
expectEqual(m[-5, default: 555], 555)
}
StdMapTestSuite.test("Map.mapValues") {
let m = initMap()
let n = m.mapValues { v in v * 2 }
expectEqual(n[1], 6)
expectEqual(n[2], 4)
expectEqual(n[3], 6)
let n2: MapIntString = m.mapValues { v in std.string("\(v * 3)") }
expectEqual(n2[1], std.string("9"))
expectEqual(n2[2], std.string("6"))
expectEqual(n2[3], std.string("9"))
let n3: UnorderedMap = m.mapValues { v in v * 4 }
expectEqual(n3[1], 12)
expectEqual(n3[2], 8)
expectEqual(n3[3], 12)
}
StdMapTestSuite.test("UnorderedMap.mapValues") {
let m = initUnorderedMap()
let n = m.mapValues { v in v * 2 }
expectEqual(n[1], 6)
expectEqual(n[2], 4)
expectEqual(n[3], 6)
let n2: UnorderedIntString = m.mapValues { v in std.string("\(v * 3)") }
expectEqual(n2[1], std.string("9"))
expectEqual(n2[2], std.string("6"))
expectEqual(n2[3], std.string("9"))
let n3: Map = m.mapValues { v in v * 4 }
expectEqual(n3[1], 12)
expectEqual(n3[2], 8)
expectEqual(n3[3], 12)
}
StdMapTestSuite.test("Map.compactMapValues") {
let m = Map([1: 1, 2: 2, 3: 3, 4: 4])
let n = m.compactMapValues { v in v % 2 == 0 ? nil : v * 2 }
expectEqual(n[1], 2)
expectNil(n[2])
expectEqual(n[3], 6)
expectNil(n[4])
let n2: MapIntString = m.compactMapValues { v in v % 2 == 0 ? nil : std.string("\(v * 3)") }
expectEqual(n2[1], std.string("3"))
expectNil(n2[2])
expectEqual(n2[3], std.string("9"))
expectNil(n2[4])
let n3: UnorderedMap = m.compactMapValues { v in v % 2 == 0 ? nil : v * 4 }
expectEqual(n3[1], 4)
expectNil(n3[2])
expectEqual(n3[3], 12)
expectNil(n3[4])
}
StdMapTestSuite.test("UnorderedMap.compactMapValues") {
let m = UnorderedMap([1: 1, 2: 2, 3: 3, 4: 4])
let n = m.compactMapValues { v in v % 2 == 0 ? nil : v * 2 }
expectEqual(n[1], 2)
expectNil(n[2])
expectEqual(n[3], 6)
expectNil(n[4])
let n2: UnorderedIntString = m.compactMapValues { v in v % 2 == 0 ? nil : std.string("\(v * 3)") }
expectEqual(n2[1], std.string("3"))
expectNil(n2[2])
expectEqual(n2[3], std.string("9"))
expectNil(n2[4])
let n3: Map = m.compactMapValues { v in v % 2 == 0 ? nil : v * 4 }
expectEqual(n3[1], 4)
expectNil(n3[2])
expectEqual(n3[3], 12)
expectNil(n3[4])
}
StdMapTestSuite.test("Map.filter") {
var m = initMap()
var n = initEmptyMap()