# [swift-evolution] Proposal: Filter split extension on Sequence to return tuple of sequences that meet criteria and that do not

Brent Royal-Gordon brent at architechies.com
Thu Jun 9 02:54:24 CDT 2016

```> Many times, I came across a scenario where I had to filter an array with a condition and filter the same array with opposite of that condition. For example:
>
> let values = [2, 4, 3, 5, 6, 9]
>
> let divisibleByTwo = values.filter { \$0 % 2 == 0 }
> let notDivisibleByTwo = values.filter { \$0 % 2 != 0 }
>
> Is there a way currently where we can filter the array into two arrays based on a condition?
>
> If not how about something like a filterSplit function where we get a tuple of values:
>
> values.filterSplit { \$0 % 2 == 0 } = ([2,4,6], [3,5,9])
>
> I have implemented this in our project and wanted to get your thoughts on it

Dave's got a pretty nice solution for the true-or-false case. If SE-0100 ("Add sequence-based initializers and merge methods to Dictionary", https://github.com/apple/swift-evolution/blob/master/proposals/0100-add-sequence-based-init-and-merge-to-dictionary.md) is accepted, you could also write an N-way, key-based version that works with any type:

let pairs = values.map { (\$0 % 3, [\$0]) }
let byThrees: [Int: Int] = Dictionary(merging: pairs, combine: +)

One could also imagine an array-based N-way version, though I'm not aware of a particularly easy-to-write implementation for it.

extension Collection {
func partition(by indexer: @noescape (Element) throws -> Int) rethrows -> [[Iterator.Element]] {
var output = [] as [[Iterator.Element]]

for elem in self {
let index = try indexer(elem)
while index >= output.endIndex {
output.append([])
}
output[index].append(elem)
}

return output
}
}

let byThrees: [Int] = values.partition { \$0 % 3 }

--
Brent Royal-Gordon
Architechies

```