Add "partitionMap" for List/Array/Seq/Set
I propose we add functions to the List/Array/Seq/Set modules that partition a collection of values into many collections of different types by a given mapper:
val partitionMap: mapper: ('a -> Choice<'b,'c>) -> source: 'a list -> 'b list * 'c list
Example (usage)
let evens,odds =
[ 0..10 ] |> List.partitionMap (fun x ->
let isEven = x % 2 = 0
match isEven with
| true -> Choice1Of2 x
| false -> Choice2Of2 x)
// val odds: int list = [1; 3; 5; 7; 9]
// val evens: int list = [0; 2; 4; 6; 8; 10]
n partitions
There could exist partitionMap(n)s for more than 2 partitions (e.g. Choice is modeled for up to 7 choices):
val partitionMap3: mapper: ('a -> Choice<'b,'c,'d>) -> source: 'a list -> 'b list * 'c list * 'd list
Non-disjoint sets
Instead of mapping an input collection of n values to 2 collections of i, j values, where i + j = n, a more general approach could be mapping n values to collections where each collection has a maximun of n values:
// partitionMap for 3 non-disjoint partitions
val partitionMap3: mapper: ('a -> Option<'b> * Option<'c> * Option<'d>) -> source: 'a list -> 'b list * 'c list * 'd list
Example
let evens,odds,specials =
[ 0..10 ] |> List.partitionMap3 (fun x ->
let isEven = x % 2 = 0
let isSpecial = x = 7
let evenResult = if isEven then Some x else None
let oddResult = if not isEven then Some x else None
let specialResult = if isSpecial then Some (float x) else None
evenResult, oddResult, specialResult
)
// val evens: int list = [0; 2; 4; 6; 8; 10]
// val odds: int list = [1; 3; 5; 7; 9]
// val specials: float list = [7.0]
Alternatives
The existing way of approaching this problem in F# is composing existing List/Array/Seq functions, or by using FSharpPlus.
Links
- The FSharpPlus implementation can be found here (in 2 versions: 1 using an optimized
ListCollector for dotnet and another using recursion - thanks @gusty for the update).
- A tweet adressing the proposal is here.
Pros and Cons
The advantages of making this adjustment to F# is having a useful function directly accessible in an idiomatic way without the need to resort to a package (FSharpPlus) or using hand-written code.
The disadvantages of making this adjustment to F# is: Having more and more functions in the core library could make it harder for beginners to see the essentials (which could be adressed by improved editor support).
Extra information
Estimated cost: XS - S
Affidavit
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.
Add "partitionMap" for List/Array/Seq/Set
I propose we add functions to the List/Array/Seq/Set modules that partition a collection of values into many collections of different types by a given mapper:
Example (usage)
n partitions
There could exist
partitionMap(n)s for more than 2 partitions (e.g.Choiceis modeled for up to 7 choices):Non-disjoint sets
Instead of mapping an input collection of
nvalues to 2 collections ofi, jvalues, wherei + j = n, a more general approach could be mappingnvalues to collections where each collection has a maximun ofnvalues:Example
Alternatives
The existing way of approaching this problem in F# is composing existing List/Array/Seq functions, or by using FSharpPlus.
Links
ListCollectorfor dotnet and another using recursion - thanks @gusty for the update).Pros and Cons
The advantages of making this adjustment to F# is having a useful function directly accessible in an idiomatic way without the need to resort to a package (FSharpPlus) or using hand-written code.
The disadvantages of making this adjustment to F# is: Having more and more functions in the core library could make it harder for beginners to see the essentials (which could be adressed by improved editor support).
Extra information
Estimated cost: XS - S
Affidavit
Please tick all that apply:
For Readers
If you would like to see this issue implemented, please click the 👍 emoji on this issue. These counts are used to generally order the suggestions by engagement.