ladvoc / BijectiveDictionary

A specialized dictionary structure offering bijective mapping and bidirectional O(1) access.
https://jacobgelman.com/posts/swift-bijective-dictionary
MIT License
4 stars 1 forks source link

Feature Parity With Standard Library Dictionary #2

Open ladvoc opened 3 months ago

ladvoc commented 3 months ago

BijectiveDictionary currently implements only a subset of the features offered by the standard library's Dictionary.
Consider the methods and properties from Dictionary that are not yet present in BijectiveDictionary and how they should be adapted. There won't always be a one-to-one correspondence between APIs, and some methods and properties may not be applicable.

Note: Since BijectiveDictionary uses the terms “left values” and “right values” instead of keys and values, the names of methods, properties, and arguments should be adjusted as needed to match this convention. For example, the init(_:uniquingKeysWith:) initializer should be renamed to init(_:uniquingLeftRightPairsWith:).

DandyLyons commented 3 months ago

I have a design question: On Dictionary .keys returns Dictionary<Key, Value>.Keys and .values returns Dictionary<Key, Value>.Values. https://developer.apple.com/documentation/swift/dictionary/keys-swift.property

These are structs, but they effectively behave like Arrays. I can iterate through them etc. https://developer.apple.com/documentation/swift/dictionary/keys-swift.struct

I would expect BijectiveDictionary.leftValues to return an "array" of left values that I can iterate through, but instead it returns the LeftValues dictionary. Also, I can't call .leftValues.keys to get an array of the keys because the actual dictionary is private (and probably should be).

tl;dr: I'm not sure how to iterate through just the left values or right values.

ladvoc commented 3 months ago

In Dictionary, the Keys and Values structs serve as “views into a collection”, a common idiom in Swift. Keys and Values are themselves not dictionaries, but rather exist to provide an external view of keys and values. Namely, they do this by conforming to Sequence, allowing iteration over keys and values respectively:

let dict = ["a": 1, "b": 2]
for key in dict.keys {
    print(key)
}
for value in dict.values {
    print(value)
}

LeftValues and RightValues are analogous to Keys and Values from Dictionary, so iterating over left and right values individually takes a similar form:

let dict: BijectiveDictionary = ["a": 1, "b": 2]
for left in dict.leftValues {
    print(left)
}
for right in dict.rightValues {
    print(right)
}

To convert left and right values to an Array, allocating storage to hold them, you can use the init<S>(S) initializer defined on Array:

let dict: BijectiveDictionary = ["a": 1, "b": 2]
let left = Array(dict.leftValues)
let right = Array(dict.rightValues)

Please let me know if this answers your question.

DandyLyons commented 2 months ago

I see, it seems like I was thrown off because it doesn't yet conform to Collection. I mistakenly thought that I wouldn't be able to iterate, if I didn't have access to .first and all the other things that Collection provides.

I have a PR for a Collection implementation that I'll send now.

DandyLyons commented 2 months ago

This talk could be instrumental in getting us to feature parity.

https://swiftcraft.uk/session/sequencing-success-exploring-swift-sequences-in-depth

DandyLyons commented 2 months ago

Are there any protocols that we don't yet conform to that we should?

ladvoc commented 2 months ago

Yes, for completeness we should implement CustomReflectable.