Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 69ed90dcfc | |||
| 33fa9622ce | |||
| 468ad1c83a | |||
| 174c21d58f | |||
| 5f076fccbb | |||
| 642b5623b7 | |||
| 03b5817530 | |||
| 7ba07fcef1 | |||
| 0e1273e2ab | |||
| 7b8b3c39a3 | |||
| 1e5c2926a7 | |||
| b678702e3d | |||
| 4e4b205dcb | |||
| b345a3e8df | |||
| 2cf9220874 | |||
| 08e9ff5371 |
+24
-9
@@ -5,7 +5,7 @@ branches:
|
||||
|
||||
# OS
|
||||
os: osx
|
||||
language: objective-c
|
||||
language: swift
|
||||
|
||||
# Xcode Project
|
||||
xcode_project: OrderedDictionary.xcodeproj
|
||||
@@ -13,31 +13,46 @@ xcode_project: OrderedDictionary.xcodeproj
|
||||
# Build Matrix
|
||||
matrix:
|
||||
include:
|
||||
# Swift 4.0 / macOS
|
||||
- osx_image: xcode9.2
|
||||
# Swift 5.0.1 / macOS
|
||||
- osx_image: xcode10.2
|
||||
xcode_scheme: OrderedDictionary-Mac
|
||||
env:
|
||||
- XCODE_SDK=macosx
|
||||
- XCODE_ACTION="build test"
|
||||
- XCODE_DESTINATION="arch=x86_64"
|
||||
- XCODE_PLAYGROUND_TARGET="x86_64-apple-macosx10.10"
|
||||
# Swift 4.0 / iOS
|
||||
- osx_image: xcode9.2
|
||||
# Swift 5.0.1 / iOS
|
||||
- osx_image: xcode10.2
|
||||
xcode_scheme: OrderedDictionary-iOS
|
||||
env:
|
||||
- XCODE_SDK=iphonesimulator
|
||||
- XCODE_ACTION="build-for-testing test-without-building"
|
||||
- XCODE_DESTINATION="platform=iOS Simulator,name=iPhone 6s,OS=10.1"
|
||||
# Swift 4.1 / macOS
|
||||
- osx_image: xcode9.3beta
|
||||
# Swift 4.1.2 / macOS
|
||||
- osx_image: xcode9.4
|
||||
xcode_scheme: OrderedDictionary-Mac
|
||||
env:
|
||||
- XCODE_SDK=macosx
|
||||
- XCODE_ACTION="build test"
|
||||
- XCODE_DESTINATION="arch=x86_64"
|
||||
- XCODE_PLAYGROUND_TARGET="x86_64-apple-macosx10.10"
|
||||
# Swift 4.1 / iOS
|
||||
- osx_image: xcode9.3beta
|
||||
# Swift 4.1.2 / iOS
|
||||
- osx_image: xcode9.4
|
||||
xcode_scheme: OrderedDictionary-iOS
|
||||
env:
|
||||
- XCODE_SDK=iphonesimulator
|
||||
- XCODE_ACTION="build-for-testing test-without-building"
|
||||
- XCODE_DESTINATION="platform=iOS Simulator,name=iPhone 6s,OS=10.1"
|
||||
# Swift 4.0.3 / macOS
|
||||
- osx_image: xcode9.2
|
||||
xcode_scheme: OrderedDictionary-Mac
|
||||
env:
|
||||
- XCODE_SDK=macosx
|
||||
- XCODE_ACTION="build test"
|
||||
- XCODE_DESTINATION="arch=x86_64"
|
||||
- XCODE_PLAYGROUND_TARGET="x86_64-apple-macosx10.10"
|
||||
# Swift 4.0.3 / iOS
|
||||
- osx_image: xcode9.2
|
||||
xcode_scheme: OrderedDictionary-iOS
|
||||
env:
|
||||
- XCODE_SDK=iphonesimulator
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
8048C8AB22D8911B0086B88B /* OrderedDictionary+Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8048C8AA22D8911B0086B88B /* OrderedDictionary+Deprecated.swift */; };
|
||||
8048C8AC22D8911B0086B88B /* OrderedDictionary+Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8048C8AA22D8911B0086B88B /* OrderedDictionary+Deprecated.swift */; };
|
||||
8055B0421E201C5D009DC3EE /* OrderedDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8055B0381E201C5D009DC3EE /* OrderedDictionary.framework */; };
|
||||
8055B0591E201DF3009DC3EE /* OrderedDictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8055B0581E201DF3009DC3EE /* OrderedDictionaryTests.swift */; };
|
||||
80A203A11F3F483700622481 /* OrderedDictionary+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80A203A01F3F483700622481 /* OrderedDictionary+Codable.swift */; };
|
||||
@@ -41,6 +43,7 @@
|
||||
8024947F2277136D00AB44C7 /* Package@swift-5.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Package@swift-5.swift"; sourceTree = "<group>"; };
|
||||
804879371E217C7700AD31A3 /* build.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = "<group>"; };
|
||||
804879381E217CA100AD31A3 /* validate-playgrounds.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "validate-playgrounds.sh"; sourceTree = "<group>"; };
|
||||
8048C8AA22D8911B0086B88B /* OrderedDictionary+Deprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrderedDictionary+Deprecated.swift"; sourceTree = "<group>"; };
|
||||
8055B0381E201C5D009DC3EE /* OrderedDictionary.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OrderedDictionary.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8055B0411E201C5D009DC3EE /* OrderedDictionary_Mac_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OrderedDictionary_Mac_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8055B0581E201DF3009DC3EE /* OrderedDictionaryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrderedDictionaryTests.swift; sourceTree = "<group>"; };
|
||||
@@ -135,6 +138,7 @@
|
||||
80E8E21C1E20301E00395E49 /* OrderedDictionary.swift */,
|
||||
80A203A01F3F483700622481 /* OrderedDictionary+Codable.swift */,
|
||||
80E8E22F1E2133D100395E49 /* OrderedDictionary+Description.swift */,
|
||||
8048C8AA22D8911B0086B88B /* OrderedDictionary+Deprecated.swift */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
@@ -346,6 +350,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8048C8AB22D8911B0086B88B /* OrderedDictionary+Deprecated.swift in Sources */,
|
||||
80E8E2301E2133D100395E49 /* OrderedDictionary+Description.swift in Sources */,
|
||||
80E8E21D1E20301E00395E49 /* OrderedDictionary.swift in Sources */,
|
||||
80A203A11F3F483700622481 /* OrderedDictionary+Codable.swift in Sources */,
|
||||
@@ -364,6 +369,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8048C8AC22D8911B0086B88B /* OrderedDictionary+Deprecated.swift in Sources */,
|
||||
80E8E2311E2133D100395E49 /* OrderedDictionary+Description.swift in Sources */,
|
||||
80E8E21F1E20425B00395E49 /* OrderedDictionary.swift in Sources */,
|
||||
80A203A21F3F4C1F00622481 /* OrderedDictionary+Codable.swift in Sources */,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
LastUpgradeVersion = "1100"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -27,6 +27,15 @@
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "8055B0371E201C5D009DC3EE"
|
||||
BuildableName = "OrderedDictionary.framework"
|
||||
BlueprintName = "OrderedDictionary-Mac"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@@ -39,17 +48,6 @@
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "8055B0371E201C5D009DC3EE"
|
||||
BuildableName = "OrderedDictionary.framework"
|
||||
BlueprintName = "OrderedDictionary-Mac"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
@@ -70,8 +68,6 @@
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
LastUpgradeVersion = "1100"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -27,6 +27,15 @@
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "80B28E961E201EC8007E3A77"
|
||||
BuildableName = "OrderedDictionary.framework"
|
||||
BlueprintName = "OrderedDictionary-iOS"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@@ -39,17 +48,6 @@
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "80B28E961E201EC8007E3A77"
|
||||
BuildableName = "OrderedDictionary.framework"
|
||||
BlueprintName = "OrderedDictionary-iOS"
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
@@ -70,8 +68,6 @@
|
||||
ReferencedContainer = "container:OrderedDictionary.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
||||
@@ -31,19 +31,3 @@ let plistDecoder = PropertyListDecoder()
|
||||
let orderedDictionary3 = try! plistDecoder.decode(OrderedDictionary<String, Int>.self, from: plistData)
|
||||
|
||||
orderedDictionary1 == orderedDictionary3
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Non-codable Type
|
||||
// ======================================================= //
|
||||
|
||||
struct NonCodableType {
|
||||
var string: String
|
||||
}
|
||||
|
||||
let orderedDictionary4: OrderedDictionary<String, NonCodableType> = [
|
||||
"A" : NonCodableType(string: "Foo"),
|
||||
"B" : NonCodableType(string: "Bar"),
|
||||
"C" : NonCodableType(string: "Baz")
|
||||
]
|
||||
|
||||
//try? jsonEncoder.encode(x)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# OrderedDictionary
|
||||
|
||||
[](https://travis-ci.org/lukaskubanek/OrderedDictionary) [](https://github.com/lukaskubanek/OrderedDictionary/releases) [](https://developer.apple.com/swift/ "Swift 4")  [](https://github.com/Carthage/Carthage)
|
||||
[](https://travis-ci.org/lukaskubanek/OrderedDictionary) [](https://github.com/lukaskubanek/OrderedDictionary/releases) [](https://developer.apple.com/swift/ "Swift 4.0+")  [](https://github.com/Carthage/Carthage)
|
||||
[](https://github.com/Carthage/Carthage) [](LICENSE.md)
|
||||
|
||||
**OrderedDictionary** is a lightweight implementation of an ordered dictionary data structure in Swift.
|
||||
@@ -13,7 +13,7 @@ Internally, `OrderedDictionary` uses a backing store composed of an instance of
|
||||
|
||||
## Requirements
|
||||
|
||||
- Swift 4.0, 4.2, 5.0
|
||||
- Swift 4.0+ (4.0, 4.2, 5.0, 5.1)
|
||||
- Xcode 9.2+
|
||||
- iOS 8.0+ / macOS 10.10+
|
||||
|
||||
@@ -36,7 +36,7 @@ Then, drag either the `OrderedDictionary.xcodeproj` or the `OrderedDictionary.fr
|
||||
Another option is to use the [Swift Package Manager](https://swift.org/package-manager/). If you prefer this option, put OrderedDictionary as a dependency to your `Package.swift`:
|
||||
|
||||
```plain
|
||||
.package(url: "https://github.com/lukaskubanek/OrderedDictionary.git", from: "2.2.2")
|
||||
.package(url: "https://github.com/lukaskubanek/OrderedDictionary.git", from: "2.3.0")
|
||||
```
|
||||
|
||||
#### Git Submodules
|
||||
|
||||
@@ -32,6 +32,9 @@ if [[ -z $XCODE_DESTINATION ]]; then
|
||||
fi
|
||||
|
||||
set -o pipefail
|
||||
|
||||
swift --version
|
||||
|
||||
xcodebuild $XCODE_ACTION \
|
||||
-project "$TRAVIS_XCODE_PROJECT" \
|
||||
-scheme "$TRAVIS_XCODE_SCHEME" \
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
extension OrderedDictionary {
|
||||
|
||||
@available(*, deprecated, message: "Please use init(values:uniquelyKeyedBy:).", renamed: "init(values:uniquelyKeyedBy:)")
|
||||
public init<S: Sequence>(
|
||||
values: S,
|
||||
keyedBy extractKey: (Value) -> Key
|
||||
) where S.Element == Value {
|
||||
self.init(values: values, uniquelyKeyedBy: extractKey)
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Please use init(values:uniquelyKeyedBy:).", renamed: "init(values:uniquelyKeyedBy:)")
|
||||
public init(
|
||||
values: [Value],
|
||||
keyedBy keyPath: KeyPath<Value, Key>
|
||||
) {
|
||||
self.init(values: values, uniquelyKeyedBy: keyPath)
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Please use init(uniqueKeysWithValues:).", renamed: "init(uniqueKeysWithValues:)")
|
||||
public init<S: Sequence>(_ elements: S) where S.Element == Element {
|
||||
self.init(uniqueKeysWithValues: elements)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,32 +27,10 @@ public struct OrderedDictionary<Key: Hashable, Value>: BidirectionalCollection {
|
||||
// MARK: - Initialization
|
||||
// ======================================================= //
|
||||
|
||||
/// Creates an empty ordered dictionary.
|
||||
/// Initializes an empty ordered dictionary.
|
||||
public init() {}
|
||||
|
||||
/// Creates an ordered dictionary from a sequence of values keyed by a key which gets extracted
|
||||
/// from the value in the provided closure.
|
||||
///
|
||||
/// - Parameter values: The sequence of values.
|
||||
/// - Parameter getKey: The closure which provides a key for the given value from the values
|
||||
/// sequence.
|
||||
public init<Values: Sequence>(
|
||||
values: Values,
|
||||
keyedBy getKey: (Value) -> Key
|
||||
) where Values.Element == Value {
|
||||
self.init(values.map { (getKey($0), $0) })
|
||||
}
|
||||
|
||||
/// Creates an ordered dictionary from a sequence of values keyed by a key loaded from the value
|
||||
/// at the given key path.
|
||||
///
|
||||
/// - Parameter values: The sequence of values.
|
||||
/// - Parameter keyPath: The key path for the value to locate its key at.
|
||||
public init(values: [Value], keyedBy keyPath: KeyPath<Value, Key>) {
|
||||
self.init(values.map { ($0[keyPath: keyPath], $0) })
|
||||
}
|
||||
|
||||
/// Creates an ordered dictionary from a regular unsorted dictionary by sorting it using the
|
||||
/// Initializes an ordered dictionary from a regular unsorted dictionary by sorting it using the
|
||||
/// the given sort function.
|
||||
///
|
||||
/// - Parameter unsorted: The unsorted dictionary.
|
||||
@@ -61,20 +39,48 @@ public struct OrderedDictionary<Key: Hashable, Value>: BidirectionalCollection {
|
||||
unsorted: Dictionary<Key, Value>,
|
||||
areInIncreasingOrder: (Element, Element) throws -> Bool
|
||||
) rethrows {
|
||||
let elements = try unsorted
|
||||
.map { (key: $0.key, value: $0.value) }
|
||||
.sorted(by: areInIncreasingOrder)
|
||||
|
||||
self.init(elements)
|
||||
let keysAndValues = try Array(unsorted).sorted(by: areInIncreasingOrder)
|
||||
self.init(uniqueKeysWithValues: keysAndValues)
|
||||
}
|
||||
|
||||
/// Creates an ordered dictionary from a sequence of key-value pairs.
|
||||
/// Initializes an ordered dictionary from a sequence of values keyed by a uniqe key extracted
|
||||
/// from the value using the given closure.
|
||||
///
|
||||
/// - Parameter elements: The key-value pairs that will make up the new ordered dictionary.
|
||||
/// Each key in `elements` must be unique.
|
||||
public init<S: Sequence>(_ elements: S) where S.Element == Element {
|
||||
for (key, value) in elements {
|
||||
precondition(!containsKey(key), "Elements sequence contains duplicate keys")
|
||||
/// - Parameter values: The sequence of values.
|
||||
/// - Parameter extractKey: The closure which extracts a key from the value. The returned keys
|
||||
/// must be unique for all values from the sequence.
|
||||
public init<S: Sequence>(
|
||||
values: S,
|
||||
uniquelyKeyedBy extractKey: (Value) -> Key
|
||||
) where S.Element == Value {
|
||||
self.init(uniqueKeysWithValues: values.map { value in
|
||||
return (extractKey(value), value)
|
||||
})
|
||||
}
|
||||
|
||||
/// Initializes an ordered dictionary from a sequence of values keyed by a unique key extracted
|
||||
/// from the value using the given key path.
|
||||
///
|
||||
/// - Parameter values: The sequence of values.
|
||||
/// - Parameter keyPath: The key path to use for extracting a key from the value. The extracted
|
||||
/// keys must be unique for all values from the sequence.
|
||||
public init<S: Sequence>(
|
||||
values: S,
|
||||
uniquelyKeyedBy keyPath: KeyPath<Value, Key>
|
||||
) where S.Element == Value {
|
||||
self.init(
|
||||
values: values,
|
||||
uniquelyKeyedBy: { $0[keyPath: keyPath] }
|
||||
)
|
||||
}
|
||||
|
||||
/// Initializes an ordered dictionary from a sequence of key-value pairs.
|
||||
///
|
||||
/// - Parameter keysAndValues: A sequence of key-value pairs to use for the new ordered
|
||||
/// dictionary. Every key in `keysAndValues` must be unique.
|
||||
public init<S: Sequence>(uniqueKeysWithValues keysAndValues: S) where S.Element == Element {
|
||||
for (key, value) in keysAndValues {
|
||||
precondition(!containsKey(key), "Sequence of key-value pairs contains duplicate keys")
|
||||
self[key] = value
|
||||
}
|
||||
}
|
||||
@@ -288,7 +294,11 @@ public struct OrderedDictionary<Key: Hashable, Value>: BidirectionalCollection {
|
||||
/// - Returns: The index for `key` and its associated value if `key` is in the ordered
|
||||
/// dictionary; otherwise, `nil`.
|
||||
public func index(forKey key: Key) -> Index? {
|
||||
#if swift(>=5.0)
|
||||
return _orderedKeys.firstIndex(of: key)
|
||||
#else
|
||||
return _orderedKeys.index(of: key)
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Returns the key-value pair at the specified index, or `nil` if there is no key-value pair
|
||||
@@ -543,7 +553,7 @@ public struct OrderedDictionary<Key: Hashable, Value>: BidirectionalCollection {
|
||||
public func sorted(
|
||||
by areInIncreasingOrder: (Element, Element) throws -> Bool
|
||||
) rethrows -> OrderedDictionary<Key, Value> {
|
||||
return OrderedDictionary(try _sortedElements(by: areInIncreasingOrder))
|
||||
return OrderedDictionary(uniqueKeysWithValues: try _sortedElements(by: areInIncreasingOrder))
|
||||
}
|
||||
|
||||
private func _sortedElements(
|
||||
@@ -552,6 +562,41 @@ public struct OrderedDictionary<Key: Hashable, Value>: BidirectionalCollection {
|
||||
return try sorted(by: areInIncreasingOrder)
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Mapping Values
|
||||
// ======================================================= //
|
||||
|
||||
/// Returns a new ordered dictionary containing the keys of this ordered dictionary with the
|
||||
/// values transformed by the given closure by preserving the original order.
|
||||
public func mapValues<T>(
|
||||
_ transform: (Value) throws -> T
|
||||
) rethrows -> OrderedDictionary<Key, T> {
|
||||
var result = OrderedDictionary<Key, T>()
|
||||
|
||||
for (key, value) in self {
|
||||
result[key] = try transform(value)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/// Returns a new ordered dictionary containing only the key-value pairs that have non-nil
|
||||
/// values as the result of transformation by the given closure by preserving the original
|
||||
/// order.
|
||||
public func compactMapValues<T>(
|
||||
_ transform: (Value) throws -> T?
|
||||
) rethrows -> OrderedDictionary<Key, T> {
|
||||
var result = OrderedDictionary<Key, T>()
|
||||
|
||||
for (key, value) in self {
|
||||
if let transformedValue = try transform(value) {
|
||||
result[key] = transformedValue
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Internal Storage
|
||||
// ======================================================= //
|
||||
@@ -612,19 +657,20 @@ public typealias OrderedDictionaryValues<Key: Hashable, Value> = LazyMapBidirect
|
||||
|
||||
extension OrderedDictionary: ExpressibleByArrayLiteral {
|
||||
|
||||
/// Creates an ordered dictionary initialized from an array literal containing a list of
|
||||
/// key-value pairs.
|
||||
/// Initializes an ordered dictionary initialized from an array literal containing a list of
|
||||
/// key-value pairs. Every key in `elements` must be unique.
|
||||
public init(arrayLiteral elements: Element...) {
|
||||
self.init(elements)
|
||||
self.init(uniqueKeysWithValues: elements)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension OrderedDictionary: ExpressibleByDictionaryLiteral {
|
||||
|
||||
/// Creates an ordered dictionary initialized from a dictionary literal.
|
||||
/// Initializes an ordered dictionary initialized from a dictionary literal. Every key in
|
||||
/// `elements` must be unique.
|
||||
public init(dictionaryLiteral elements: (Key, Value)...) {
|
||||
self.init(elements.map { element in
|
||||
self.init(uniqueKeysWithValues: elements.map { element in
|
||||
let (key, value) = element
|
||||
return (key: key, value: value)
|
||||
})
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.2.2</string>
|
||||
<string>2.3.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -42,7 +42,7 @@ class OrderedDictionaryTests: XCTestCase {
|
||||
("C", 3)
|
||||
]
|
||||
|
||||
let expected = OrderedDictionary<String, Int>([
|
||||
let expected = OrderedDictionary<String, Int>(uniqueKeysWithValues: [
|
||||
(key: "A", value: 1),
|
||||
(key: "B", value: 2),
|
||||
(key: "C", value: 3)
|
||||
@@ -58,7 +58,7 @@ class OrderedDictionaryTests: XCTestCase {
|
||||
"C": 3
|
||||
]
|
||||
|
||||
let expected = OrderedDictionary<String, Int>([
|
||||
let expected = OrderedDictionary<String, Int>(uniqueKeysWithValues: [
|
||||
(key: "A", value: 1),
|
||||
(key: "B", value: 2),
|
||||
(key: "C", value: 3)
|
||||
@@ -70,10 +70,10 @@ class OrderedDictionaryTests: XCTestCase {
|
||||
func testInitializationUsingValuesAndKeyProviderClosure() {
|
||||
let actual = OrderedDictionary(
|
||||
values: [1, 2, 3],
|
||||
keyedBy: { "\($0)" }
|
||||
uniquelyKeyedBy: { "\($0)" }
|
||||
)
|
||||
|
||||
let expected = OrderedDictionary<String, Int>([
|
||||
let expected = OrderedDictionary<String, Int>(uniqueKeysWithValues: [
|
||||
(key: "1", value: 1),
|
||||
(key: "2", value: 2),
|
||||
(key: "3", value: 3)
|
||||
@@ -89,10 +89,10 @@ class OrderedDictionaryTests: XCTestCase {
|
||||
TestValue(string: "B"),
|
||||
TestValue(string: "C")
|
||||
],
|
||||
keyedBy: \.string
|
||||
uniquelyKeyedBy: \.string
|
||||
)
|
||||
|
||||
let expected = OrderedDictionary<String, TestValue>([
|
||||
let expected = OrderedDictionary<String, TestValue>(uniqueKeysWithValues: [
|
||||
(key: "A", value: TestValue(string: "A")),
|
||||
(key: "B", value: TestValue(string: "B")),
|
||||
(key: "C", value: TestValue(string: "C"))
|
||||
@@ -113,7 +113,7 @@ class OrderedDictionaryTests: XCTestCase {
|
||||
areInIncreasingOrder: { $0.key < $1.key }
|
||||
)
|
||||
|
||||
let expected = OrderedDictionary([
|
||||
let expected = OrderedDictionary(uniqueKeysWithValues: [
|
||||
(key: 1, value: "bar"),
|
||||
(key: 2, value: "foo"),
|
||||
(key: 3, value: "bam"),
|
||||
@@ -133,7 +133,7 @@ class OrderedDictionaryTests: XCTestCase {
|
||||
3: "bam"
|
||||
].sorted(by: { $0.key < $1.key })
|
||||
|
||||
let expected = OrderedDictionary([
|
||||
let expected = OrderedDictionary(uniqueKeysWithValues: [
|
||||
(key: 1, value: "bar"),
|
||||
(key: 2, value: "foo"),
|
||||
(key: 3, value: "bam"),
|
||||
@@ -511,6 +511,28 @@ class OrderedDictionaryTests: XCTestCase {
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Mapping Values
|
||||
// ======================================================= //
|
||||
|
||||
func testMapValues() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3, "D": 4]
|
||||
|
||||
let actual = orderedDictionary.mapValues { String($0) }
|
||||
let expected: OrderedDictionary<String, String> = ["A": "1", "B": "2", "C": "3", "D": "4"]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
func testCompactMapValues() {
|
||||
let orderedDictionary: OrderedDictionary<String, Int> = ["A": 1, "B": 2, "C": 3, "D": 4]
|
||||
|
||||
let actual = orderedDictionary.compactMapValues { $0 % 2 == 0 ? String($0) : nil }
|
||||
let expected: OrderedDictionary<String, String> = ["B": "2", "D": "4"]
|
||||
|
||||
XCTAssertEqual(actual, expected)
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
// MARK: - Slices
|
||||
// ======================================================= //
|
||||
|
||||
Reference in New Issue
Block a user