apple / swift-collections

Commonly used data structures for Swift
Apache License 2.0
3.55k stars 270 forks source link

OrderedSet `append(contentsOf:)` with insertion check result/results #329

Open LePips opened 5 months ago

LePips commented 5 months ago

Motivation

I am essentially using OrderedSet as the data source for a UICollectionView wrapper. In said wrapper, I allow passing in an OrderedSet, but I would also like to allow passing in any Sequence (where Element: Hashable) where I would instead create the necessary OrderedSet. Additionally, I would like to log a warning if the given sequence contained duplicates and will result in unexpected behavior, similar to SwiftUI's warnings with ForEach/etc.

Problem

Currently, append(contentsOf:) doesn't return any insertion results like append does. I think that generally this would be helpful.

Design

The basic idea can be done with the new function append(checkingContentsOf:):

@inlinable
@discardableResult
mutating func append(checkingContentsOf elements: some Sequence<Element>) -> [(inserted: Bool, index: Int)] {
    var results: [(Bool, Int)] = []

    for item in elements {
        results.append(append(item))
    }

    return results
}

However that can be a bit heavy for unexpected long sequences and I would have to iterate over the results for duplication check. So instead we can just check instead if the given sequence contained any duplicates:

@inlinable
@discardableResult
mutating func append(checkingContentsOf elements: some Sequence<Element>) -> Bool {
    var didContainDuplicate = false

    for item in elements {
        if append(item).inserted {
            didContainDuplicate = true
        }
    }

    return didContainDuplicate
}

I propose that one of these, or something similar, be implemented on OrderedSet or that the current append(contentsOf:) gains a discardable return result.