diff --git a/gitbook/SUMMARY.md b/gitbook/SUMMARY.md index f69647b6..cc16a124 100644 --- a/gitbook/SUMMARY.md +++ b/gitbook/SUMMARY.md @@ -26,11 +26,15 @@ * [sequenceResultM](list/sequenceResultM.md) * [traverseResultA](list/traverseResultA.md) * [sequenceResultA](list/sequenceResultA.md) + * [partitionResults](list/partitionResults.md) * Sequences * [traverseResultM](seq/traverseResultM.md) * [sequenceResultM](seq/sequenceResultM.md) * [traverseResultA](seq/traverseResultA.md) * [sequenceResultA](seq/sequenceResultA.md) + * [partitionResults](seq/partitionResults.md) + * Arrays + * [partitionResults](array/partitionResults.md) * Transforms * [ofChoice](result/ofChoice.md) diff --git a/gitbook/array/partitionResults.md b/gitbook/array/partitionResults.md new file mode 100644 index 00000000..39ab0a2a --- /dev/null +++ b/gitbook/array/partitionResults.md @@ -0,0 +1,53 @@ +# Array.partitionResults + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +Result<'ok, 'error>[] -> 'ok[] * 'error[] +``` + +Separates an array of `Result` values into a tuple of the `Ok` values and the `Error` values, preserving order within each group. + +## Examples + +### Example 1 + +```fsharp +let results = [| Ok 1; Error "bad"; Ok 2; Ok 3; Error "worse" |] + +results |> Array.partitionResults +// ([| 1; 2; 3 |], [| "bad"; "worse" |]) +``` + +### Example 2 + +```fsharp +// string -> Result +let tryParseInt str = + match System.Int32.TryParse str with + | true, x -> Ok x + | false, _ -> Error (sprintf "unable to parse '%s' to integer" str) + +[| "1"; "foo"; "3"; "bar" |] +|> Array.map tryParseInt +|> Array.partitionResults +// ([| 1; 3 |], [| "unable to parse 'foo' to integer"; "unable to parse 'bar' to integer" |]) +``` + +### Example 3 + +All Ok values: + +```fsharp +[| Ok 1; Ok 2; Ok 3 |] |> Array.partitionResults +// ([| 1; 2; 3 |], [||]) +``` + +All Error values: + +```fsharp +[| Error "a"; Error "b" |] |> Array.partitionResults +// ([||], [| "a"; "b" |]) +``` diff --git a/gitbook/list/partitionResults.md b/gitbook/list/partitionResults.md new file mode 100644 index 00000000..285ce497 --- /dev/null +++ b/gitbook/list/partitionResults.md @@ -0,0 +1,53 @@ +# List.partitionResults + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +Result<'ok, 'error> list -> 'ok list * 'error list +``` + +Separates a list of `Result` values into a tuple of the `Ok` values and the `Error` values, preserving order within each group. + +## Examples + +### Example 1 + +```fsharp +let results = [Ok 1; Error "bad"; Ok 2; Ok 3; Error "worse"] + +results |> List.partitionResults +// ([1; 2; 3], ["bad"; "worse"]) +``` + +### Example 2 + +```fsharp +// string -> Result +let tryParseInt str = + match System.Int32.TryParse str with + | true, x -> Ok x + | false, _ -> Error (sprintf "unable to parse '%s' to integer" str) + +["1"; "foo"; "3"; "bar"] +|> List.map tryParseInt +|> List.partitionResults +// ([1; 3], ["unable to parse 'foo' to integer"; "unable to parse 'bar' to integer"]) +``` + +### Example 3 + +All Ok values: + +```fsharp +[Ok 1; Ok 2; Ok 3] |> List.partitionResults +// ([1; 2; 3], []) +``` + +All Error values: + +```fsharp +[Error "a"; Error "b"] |> List.partitionResults +// ([], ["a"; "b"]) +``` diff --git a/gitbook/seq/partitionResults.md b/gitbook/seq/partitionResults.md new file mode 100644 index 00000000..72a901e0 --- /dev/null +++ b/gitbook/seq/partitionResults.md @@ -0,0 +1,55 @@ +# Seq.partitionResults + +Namespace: `FsToolkit.ErrorHandling` + +## Function Signature + +```fsharp +seq> -> 'ok[] * 'error[] +``` + +Separates a sequence of `Result` values into a tuple of the `Ok` values and the `Error` values as arrays, preserving order within each group. + +See also [Array.partitionResults](../array/partitionResults.md). + +## Examples + +### Example 1 + +```fsharp +let results = seq { Ok 1; Error "bad"; Ok 2; Ok 3; Error "worse" } + +results |> Seq.partitionResults +// ([| 1; 2; 3 |], [| "bad"; "worse" |]) +``` + +### Example 2 + +```fsharp +// string -> Result +let tryParseInt str = + match System.Int32.TryParse str with + | true, x -> Ok x + | false, _ -> Error $"unable to parse '{str}' to integer" + +["1"; "foo"; "3"; "bar"] +|> Seq.map tryParseInt +|> Seq.partitionResults +// ([| 1; 3 |], [| "unable to parse 'foo' to integer"; "unable to parse 'bar' to integer" |]) +``` + +### Example 3 + +All Ok values: + +```fsharp +seq { Ok 1; Ok 2; Ok 3 } |> Seq.partitionResults +// ([| 1; 2; 3 |], [||]) +``` + +All Error values: + +```fsharp +seq { Error "a"; Error "b" } |> Seq.partitionResults +// ([||], [| "a"; "b" |]) +``` diff --git a/src/FsToolkit.ErrorHandling/Array.fs b/src/FsToolkit.ErrorHandling/Array.fs index ac2b0409..546f92a6 100644 --- a/src/FsToolkit.ErrorHandling/Array.fs +++ b/src/FsToolkit.ErrorHandling/Array.fs @@ -233,3 +233,22 @@ module Array = let sequenceVOptionM xs = traverseVOptionM id xs #endif + + /// + /// Partitions an array of results into a tuple of the ok values and the error values. + /// + /// The input array of results. + /// A tuple where the first element is an array of all Ok values and the second is an array of all Error values. + let partitionResults (input: Result<'ok, 'error>[]) : 'ok[] * 'error[] = + if System.Object.ReferenceEquals(input, null) then + nullArg (nameof input) + + let oks = ResizeArray() + let errors = ResizeArray() + + for x in input do + match x with + | Ok v -> oks.Add v + | Error e -> errors.Add e + + oks.ToArray(), errors.ToArray() diff --git a/src/FsToolkit.ErrorHandling/List.fs b/src/FsToolkit.ErrorHandling/List.fs index c1888077..545ad17a 100644 --- a/src/FsToolkit.ErrorHandling/List.fs +++ b/src/FsToolkit.ErrorHandling/List.fs @@ -274,3 +274,22 @@ module List = #endif + + /// + /// Partitions a list of results into a tuple of the ok values and the error values. + /// + /// The input list of results. + /// A tuple where the first element is a list of all Ok values and the second is a list of all Error values. + let partitionResults (input: Result<'ok, 'error> list) : 'ok list * 'error list = + if System.Object.ReferenceEquals(input, null) then + nullArg (nameof input) + + let oks = ResizeArray() + let errors = ResizeArray() + + for x in input do + match x with + | Ok v -> oks.Add v + | Error e -> errors.Add e + + List.ofSeq oks, List.ofSeq errors diff --git a/src/FsToolkit.ErrorHandling/Seq.fs b/src/FsToolkit.ErrorHandling/Seq.fs index 01c952e1..7323f63c 100644 --- a/src/FsToolkit.ErrorHandling/Seq.fs +++ b/src/FsToolkit.ErrorHandling/Seq.fs @@ -501,3 +501,22 @@ let traverseVOptionM f xs = let sequenceVOptionM xs = traverseVOptionM id xs #endif + +/// +/// Partitions a sequence of results into a tuple of the ok values and the error values. +/// +/// The input sequence of results. +/// A tuple where the first element is an array of all Ok values and the second is an array of all Error values. +let partitionResults (input: SeqNull>) : 'ok[] * 'error[] = + if isNull input then + nullArg (nameof input) + + let oks = ResizeArray() + let errors = ResizeArray() + + for x in input do + match x with + | Ok v -> oks.Add v + | Error e -> errors.Add e + + oks.ToArray(), errors.ToArray()