-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
96 additions
and
0 deletions.
There are no files selected for viewing
86 changes: 86 additions & 0 deletions
86
Sources/BijectiveDictionary/BijectiveDictionary+Conflict.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// ============================================================= | ||
// File: BijectiveDictionary+Conflict.swift | ||
// Project: BijectiveDictionary | ||
// ------------------------------------------------------------- | ||
// Created by Jacob Gelman on 09/11/2024 | ||
// Copyright © 2024 Jacob Gelman. All rights reserved. | ||
// ============================================================= | ||
|
||
extension BijectiveDictionary { | ||
|
||
/// The result of a conflict check. | ||
@frozen | ||
public enum Conflict: Hashable { | ||
|
||
/// The left value is already present. | ||
case left | ||
|
||
/// The right value is already present. | ||
case right | ||
|
||
/// Both the left and right values are already present in the same pair. | ||
case pair | ||
|
||
/// Both the left and right values are already present across two different pairs. | ||
case both(otherLeft: Left, otherRight: Right) | ||
} | ||
|
||
/// Check if a conflict exists between the given pair and the contents of the dictionary that, if inserted, | ||
/// would override an existing pair or break the bijective property. | ||
/// | ||
/// - Parameter pair: The left-right pair to perform the conflict check against. | ||
/// - Returns: The conflict, if one exists, or `nil`, indicating neither the left nor right value already | ||
/// exist in the dictionary. | ||
/// - Complexity: O(1) | ||
/// | ||
/// The following example demonstrates creating a dictionary mapping element symbols | ||
/// to their atomic numbers and checking to see if a conflict exists: | ||
/// ```swift | ||
/// let dict: BijectiveDictionary = ["Ti": 22, "Si": 14, "He": 2] | ||
/// | ||
/// guard let conflict = dict.conflict(for: ("Ti", 2)) else { | ||
/// print("No conflict") | ||
/// return | ||
/// } | ||
/// switch conflict { | ||
/// case .left: | ||
/// print("Symbol already present") | ||
/// case .right: | ||
/// print("Atomic number already present") | ||
/// case .pair: | ||
/// print("Pair already exists") | ||
/// case .both(let otherSymbol, let otherNumber): | ||
/// print("Other symbol: \(otherSymbol), other number: \(otherNumber)") | ||
/// } | ||
/// // prints "Other symbol: He, other number: 22" | ||
/// ``` | ||
@inlinable | ||
public func conflict(with pair: Element) -> Conflict? { | ||
let existing = (findByLeft(pair.left), findByRight(pair.right)) | ||
return switch existing { | ||
case (nil, nil): nil | ||
case (nil, .some): .right | ||
case (.some, nil): .left | ||
case (.some(let byLeft), .some(let byRight)): | ||
if byLeft.left != byRight.left || byLeft.right != byRight.right { | ||
.both(otherLeft: byRight.left, otherRight: byLeft.right) | ||
} else { | ||
.pair | ||
} | ||
} | ||
} | ||
|
||
/// Find a pair in the dictionary by left value. | ||
@inlinable | ||
internal func findByLeft(_ leftValue: Left) -> Element? { | ||
This comment has been minimized.
Sorry, something went wrong. |
||
guard let rightValue = self[left: leftValue] else { return nil } | ||
return (leftValue, rightValue) | ||
} | ||
|
||
/// Find a pair in the dictionary by right value. | ||
@inlinable | ||
internal func findByRight(_ rightValue: Right) -> Element? { | ||
guard let leftValue = self[right: rightValue] else { return nil } | ||
return (leftValue, rightValue) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Might be clearer if we named this
findPairByLeft(_:)
Also, is this unsafe to use outside the library? Perhaps we should make this public. I don't see a reason not to.