Skip to content

Commit

Permalink
Implement discard conflicting initializer
Browse files Browse the repository at this point in the history
  • Loading branch information
ladvoc committed Sep 14, 2024
1 parent 102eed0 commit dc62d25
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
15 changes: 15 additions & 0 deletions Sources/BijectiveDictionary/BijectiveDictionary+Initializers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ extension BijectiveDictionary {
self._rtl = Dictionary(uniqueKeysWithValues: reversePairs)
}

/// Creates a new dictionary from the left-right pairs in the given sequence, discarding any conflicting pairs.

This comment has been minimized.

Copy link
@DandyLyons

DandyLyons Sep 14, 2024

Collaborator

I recommend writing discarding conflicting pairs (if any).

///
/// - Parameter leftRightPairs: A sequence of left-right pairs to use for the new dictionary.

This comment has been minimized.

Copy link
@DandyLyons

DandyLyons Sep 14, 2024

Collaborator

We should probably define more deeply what "conflicting" means here. I would assume that here it means the same thing as the cases documented in What is a Duplicate?.md Why don't we link to that article here?

/// - Complexity: O(*n*), where *n* is the number of key-value pairs in the given sequence.
@inlinable public init<S>(
discardConflicting leftRightPairs: S

This comment has been minimized.

Copy link
@DandyLyons

DandyLyons Sep 14, 2024

Collaborator

I like the idea of this initializer. It's clear that the conflicts will be discarded. It's also nice that it's not failable or throwing.

Perhaps discardingConflicts would be clearer.

) where S: Sequence, S.Element == Element {
self.init()
for pair in leftRightPairs where conflict(with: pair) == nil {
_ltr[pair.left] = pair.right
_rtl[pair.right] = pair.left
}
_invariantCheck()
}

/// Creates a bijective dictionary from a standard dictionary.
///
/// Unlike a standard dictionary which only requires its keys be unique, a bijective
Expand Down
7 changes: 7 additions & 0 deletions Tests/BijectiveDictionaryTests/BijectiveDictionaryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -299,4 +299,11 @@ func conflict() {
#expect(dict.conflict(with: ("A", 1)) == .pair)
#expect(dict.conflict(with: ("A", 3)) == .both(otherLeft: "C", otherRight: 1))
}

@Test
func discardConflicting() {
let pairs = [("A", 1), ("B", 1), ("A", 10), ("C", 4), ("C", 4), ("E", 5), ("A", 5)]

This comment has been minimized.

Copy link
@DandyLyons

DandyLyons Sep 14, 2024

Collaborator

I just realized a potential issue with this API. Currently init(discardConflicting:) receives a Sequence, which could or could not be ordered. If an unordered Sequence is passed into it (such as a Set), then it is probably non-deterministic which pairs will then be discarded.

Potential solutions

  1. We could require an ordered collection.
  2. We could warn in the documentation that the discarding is non-deterministic. Then it's the users responsibility to figure that out. (I don't think I like this approach.)
let dict = BijectiveDictionary(discardConflicting: pairs)
#expect(dict == ["A": 1, "C": 4, "E": 5])
}
#endif

0 comments on commit dc62d25

Please sign in to comment.