In Swift, an efficient function that separates an array into 2 arrays based on a predicate

后端 未结 7 1113
太阳男子
太阳男子 2020-12-15 04:40

Note: I\'m currently still using Swift 2.2, but open to Swift 3 solutions as well

I\'m looking to create a function that operates very closely to filter

7条回答
  •  悲哀的现实
    2020-12-15 05:01

    Solution A

    For fewer elements this may be fastest.

    extension Array {
        func stablePartition(by condition: (Element) -> Bool) -> ([Element], [Element]) {
            var matching = [Element]()
            var nonMatching = [Element]()
            for element in self {
                if condition(element) {
                    matching.append(element)
                } else {
                    nonMatching.append(element)
                }
            }
            return (matching, nonMatching)
        }
    }
    

    Usage

    let numbers = [1,2,3,4,5,6,7,8,9,10]
    let (divisibleBy3, theRest) = numbers.stablePartition { $0 % 3 == 0 }
    print("divisible by 3: \(divisibleBy3), the rest: \(theRest)")
    // divisible by 3: [3, 6, 9], the rest: [1, 2, 4, 5, 7, 8, 10]
    

    Solution B

    For many elements this may be faster, because of fewer allocations. I have not measured performance.

    extension Array {
        public func stablePartition(by condition: (Element) throws -> Bool) rethrows -> ([Element], [Element]) {
            var indexes = Set()
            for (index, element) in self.enumerated() {
                if try condition(element) {
                    indexes.insert(index)
                }
            }
            var matching = [Element]()
            matching.reserveCapacity(indexes.count)
            var nonMatching = [Element]()
            nonMatching.reserveCapacity(self.count - indexes.count)
            for (index, element) in self.enumerated() {
                if indexes.contains(index) {
                    matching.append(element)
                } else {
                    nonMatching.append(element)
                }
            }
            return (matching, nonMatching)
        }
    }
    

提交回复
热议问题