From eb79c18e93b4a2ebd4416d2d22bf2c4f7d8d0ff9 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Wed, 15 Mar 2023 21:44:07 +0100 Subject: [PATCH 1/6] zip function added --- src/FSharp.Core/array.fs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/FSharp.Core/array.fs b/src/FSharp.Core/array.fs index a4a80bc9789..9d80096a381 100644 --- a/src/FSharp.Core/array.fs +++ b/src/FSharp.Core/array.fs @@ -2078,6 +2078,28 @@ module Array = yield new ArraySegment<'T>(array, offset, maxIdxExclusive - offset) |] + [] + let zip (array1: _[]) (array2: _[]) = + checkNonNull "array1" array1 + checkNonNull "array2" array2 + let len1 = array1.Length + + if len1 <> array2.Length then + invalidArgDifferentArrayLength "array1" array1.Length "array2" array2.Length + + let res = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked len1 + let inputChunks = createPartitionsUpTo array1.Length array1 + Parallel.For( + 0, + inputChunks.Length, + fun chunkIdx -> + let chunk = inputChunks[chunkIdx] + for elemIdx = chunk.Offset to (chunk.Offset + chunk.Count - 1) do + res.[i] <- (array1.[i], array2.[i])) + |> ignore + + res + let inline groupByImplParallel (comparer: IEqualityComparer<'SafeKey>) ([] keyf: 'T -> 'SafeKey) From 10523b8abfe299b303dc5127eb97ae3e7c0a589a Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Wed, 15 Mar 2023 21:44:45 +0100 Subject: [PATCH 2/6] fantomas'd --- src/FSharp.Core/array.fs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/FSharp.Core/array.fs b/src/FSharp.Core/array.fs index 9d80096a381..7e8c17b0a9e 100644 --- a/src/FSharp.Core/array.fs +++ b/src/FSharp.Core/array.fs @@ -2089,13 +2089,16 @@ module Array = let res = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked len1 let inputChunks = createPartitionsUpTo array1.Length array1 + Parallel.For( 0, inputChunks.Length, fun chunkIdx -> let chunk = inputChunks[chunkIdx] + for elemIdx = chunk.Offset to (chunk.Offset + chunk.Count - 1) do - res.[i] <- (array1.[i], array2.[i])) + res.[i] <- (array1.[i], array2.[i]) + ) |> ignore res From 3b936e65d1b2a367a872aa0d85df3b17763a73f1 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Wed, 15 Mar 2023 21:54:27 +0100 Subject: [PATCH 3/6] Array.Parallel.filter --- src/FSharp.Core/array.fs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/FSharp.Core/array.fs b/src/FSharp.Core/array.fs index 7e8c17b0a9e..79c86d2ea56 100644 --- a/src/FSharp.Core/array.fs +++ b/src/FSharp.Core/array.fs @@ -2218,8 +2218,7 @@ module Array = Parallel.For(0, count, (fun i -> result.[i] <- initializer i)) |> ignore result - [] - let partition predicate (array: 'T[]) = + let countAndCollectTrueItems predicate (array: 'T[]) = checkNonNull "array" array let inputLength = array.Length @@ -2242,10 +2241,28 @@ module Array = ) |> ignore + trueLength, isTrue + + [] + let filter predicate (array: 'T[]) = + let trueLength, isTrue = countAndCollectTrueItems predicate array + let res = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked trueLength + let mutable resIdx = 0 + + for i = 0 to isTrue.Length - 1 do + if isTrue.[i] then + res.[resIdx] <- array.[i] + resIdx <- resIdx + 1 + + res + + [] + let partition predicate (array: 'T[]) = + let trueLength, isTrue = countAndCollectTrueItems predicate array let res1 = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked trueLength let res2 = - Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked (inputLength - trueLength) + Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked (array.Length - trueLength) let mutable iTrue = 0 let mutable iFalse = 0 From f5641eb09a3aeeaf232af6d4af496d057a5bf039 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 16 Mar 2023 10:51:37 +0100 Subject: [PATCH 4/6] .filter , .zip --- src/FSharp.Core/array.fs | 2 +- src/FSharp.Core/array.fsi | 44 +++++++++++++++++++ ...p.Core.SurfaceArea.netstandard20.debug.bsl | 4 +- ...Core.SurfaceArea.netstandard20.release.bsl | 4 +- ...p.Core.SurfaceArea.netstandard21.debug.bsl | 4 +- ...Core.SurfaceArea.netstandard21.release.bsl | 4 +- .../ArrayModule.fs | 14 ++++++ .../ArrayModule2.fs | 17 ++++++- .../CollectionModulesConsistency.fs | 10 +++-- 9 files changed, 93 insertions(+), 10 deletions(-) diff --git a/src/FSharp.Core/array.fs b/src/FSharp.Core/array.fs index 79c86d2ea56..71c472624f0 100644 --- a/src/FSharp.Core/array.fs +++ b/src/FSharp.Core/array.fs @@ -2097,7 +2097,7 @@ module Array = let chunk = inputChunks[chunkIdx] for elemIdx = chunk.Offset to (chunk.Offset + chunk.Count - 1) do - res.[i] <- (array1.[i], array2.[i]) + res[elemIdx] <- (array1[elemIdx], array2[elemIdx]) ) |> ignore diff --git a/src/FSharp.Core/array.fsi b/src/FSharp.Core/array.fsi index ca8e2013493..08de32b03d7 100644 --- a/src/FSharp.Core/array.fsi +++ b/src/FSharp.Core/array.fsi @@ -3430,3 +3430,47 @@ module Array = /// [] val partition: predicate:('T -> bool) -> array:'T[] -> 'T[] * 'T[] + + /// Combines the two arrays into an array of pairs. The two arrays must have equal lengths, otherwise an ArgumentException is + /// raised. + /// + /// The first input array. + /// The second input array. + /// + /// Thrown when either of the input arrays is null. + /// Thrown when the input arrays differ in length. + /// + /// The array of tupled elements. + /// + /// + /// + /// let numbers = [|1; 2|] + /// let names = [|"one"; "two"|] + /// + /// Array.Parallel.zip numbers names + /// + /// Evaluates to [| (1, "one"); (2, "two") |]. + /// + [] + val zip: array1:'T1[] -> array2:'T2[] -> ('T1 * 'T2)[] + + /// Returns a new collection containing only the elements of the collection + /// for which the given predicate returns "true". + /// + /// The function to test the input elements. + /// The input array. + /// + /// An array containing the elements for which the given predicate returns true. + /// + /// Thrown when the input array is null. + /// + /// + /// + /// let inputs = [| 1; 2; 3; 4 |] + /// + /// inputs |> Array.Parallel.filter (fun elm -> elm % 2 = 0) + /// + /// Evaluates to [| 2; 4 |] + /// + [] + val filter: predicate:('T -> bool) -> array:'T[] -> 'T[] \ No newline at end of file diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl index cfa1d024b69..bf416221a20 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl @@ -40,15 +40,17 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32 Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]]) Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32) Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl index 0c4153eb824..2940316fa19 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl @@ -40,15 +40,17 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32 Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]]) Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32) Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl index 99505e2972c..7e6adfec243 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl @@ -40,15 +40,17 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32 Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]]) Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32) Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl index ee1efd4c674..d4fefa49597 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl @@ -40,15 +40,17 @@ Microsoft.FSharp.Collections.Array4DModule: T[,,,] Create[T](Int32, Int32, Int32 Microsoft.FSharp.Collections.Array4DModule: T[,,,] Initialize[T](Int32, Int32, Int32, Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]]]]) Microsoft.FSharp.Collections.Array4DModule: T[,,,] ZeroCreate[T](Int32, Int32, Int32, Int32) Microsoft.FSharp.Collections.Array4DModule: Void Set[T](T[,,,], Int32, Int32, Int32, Int32, T) -Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] TryFindIndex[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[TResult] TryPick[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Microsoft.FSharp.Core.FSharpOption`1[T] TryFind[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Collect[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult[]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] MapIndexed[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,TResult]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: TResult[] Map[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,TResult], T[]) +Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Filter[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: T[] Initialize[T](Int32, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,T]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Void IterateIndexed[T](Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit]], T[]) Microsoft.FSharp.Collections.ArrayModule+Parallel: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], T[]) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs index e36ad305c88..6f71fabb8aa 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs @@ -708,6 +708,20 @@ type ArrayModule() = CheckThrowsArgumentNullException (fun () -> Array.filter funcStr nullArr |> ignore) () + + [] + member this.ParallelFilter () = + let assertSameBehavior predicate arr = + let sequentialZip = Array.filter predicate arr + let paraZip = Array.Parallel.filter predicate arr + Assert.AreEqual(sequentialZip, paraZip) + + [| 1..20 |] |> assertSameBehavior (fun x -> x%5 = 0) + [|"Lists"; "are"; "a"; "commonly"; "data";"structor" |] |> assertSameBehavior (fun x -> x.Length > 4) + [| |] |> assertSameBehavior (fun x -> x%5 = 0) + let nullArr = null:int[] + CheckThrowsArgumentNullException (fun () -> Array.Parallel.filter (fun x -> x%5 = 0) nullArr |> ignore) + [] member this.Filter2 () = diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs index b10ce17fb2e..496b560d72e 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule2.fs @@ -1259,7 +1259,22 @@ type ArrayModule2() = // len1 <> len2 CheckThrowsArgumentException(fun () -> Array.zip [|1..10|] [|2..20|] |> ignore) - () + [] + member this.ParallelZip() = + let assertSameBehaviour arr1 arr2 = + let sequentialZip = Array.zip arr1 arr2 + let paraZip = Array.Parallel.zip arr1 arr2 + Assert.AreEqual(sequentialZip, paraZip) + + assertSameBehaviour [|1..3|] [|2..2..6|] + assertSameBehaviour[|"A"; "B"; "C" ; "D" |] [|"a";"b";"c";"d"|] + assertSameBehaviour[||] [||] + + // null array + let nullArr = null:string[] + CheckThrowsArgumentNullException (fun () -> Array.Parallel.zip nullArr nullArr |> ignore) + // len1 <> len2 + CheckThrowsArgumentException(fun () -> Array.Parallel.zip [|1..10|] [|2..20|] |> ignore) [] member this.Zip3() = diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs index 0494f9682d4..9711ee8a441 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs @@ -253,7 +253,8 @@ let filter<'a when 'a : equality> (xs : 'a []) predicate = let s = xs |> Seq.filter predicate let l = xs |> List.ofArray |> List.filter predicate let a = xs |> Array.filter predicate - Seq.toArray s = a && List.toArray l = a + let pa = xs |> Array.Parallel.filter predicate + pa = a && Seq.toArray s = a && List.toArray l = a [] let ``filter is consistent`` () = @@ -1286,9 +1287,10 @@ let zip<'a when 'a : equality> (xs':('a*'a) []) = let xs = Array.map fst xs' let xs2 = Array.map snd xs' let s = runAndCheckErrorType (fun () -> Seq.zip xs xs2 |> Seq.toArray) - let l = runAndCheckErrorType (fun () -> List.zip (List.ofSeq xs) (List.ofSeq xs2) |> List.toArray) - let a = runAndCheckErrorType (fun () -> Array.zip (Array.ofSeq xs) (Array.ofSeq xs2)) - consistency "zip" s l a + let l = runAndCheckErrorType (fun () -> List.zip (List.ofArray xs) (List.ofArray xs2) |> List.toArray) + let a = runAndCheckErrorType (fun () -> Array.zip xs xs2) + let pa = runAndCheckErrorType (fun () -> Array.Parallel.zip xs xs2) + consistencyIncludingParallel "zip" s l a pa [] let ``zip is consistent for collections with equal length`` () = From c2c70dde226314d649da010f9bc085998445f183 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 20 Mar 2023 11:29:36 +0100 Subject: [PATCH 5/6] Experimental attribute added --- src/FSharp.Core/array.fsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/FSharp.Core/array.fsi b/src/FSharp.Core/array.fsi index 08de32b03d7..866016908d5 100644 --- a/src/FSharp.Core/array.fsi +++ b/src/FSharp.Core/array.fsi @@ -3452,6 +3452,7 @@ module Array = /// Evaluates to [| (1, "one"); (2, "two") |]. /// [] + [] val zip: array1:'T1[] -> array2:'T2[] -> ('T1 * 'T2)[] /// Returns a new collection containing only the elements of the collection @@ -3473,4 +3474,5 @@ module Array = /// Evaluates to [| 2; 4 |] /// [] + [] val filter: predicate:('T -> bool) -> array:'T[] -> 'T[] \ No newline at end of file From edbc38d971c444884c0235d9c7d678c9078c85d2 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 20 Mar 2023 20:00:25 +0100 Subject: [PATCH 6/6] Apply suggestions from code review Co-authored-by: Petr --- src/FSharp.Core/array.fs | 2 +- src/FSharp.Core/array.fsi | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FSharp.Core/array.fs b/src/FSharp.Core/array.fs index 71c472624f0..2a8a48a641f 100644 --- a/src/FSharp.Core/array.fs +++ b/src/FSharp.Core/array.fs @@ -2085,7 +2085,7 @@ module Array = let len1 = array1.Length if len1 <> array2.Length then - invalidArgDifferentArrayLength "array1" array1.Length "array2" array2.Length + invalidArgDifferentArrayLength "array1" len1 "array2" array2.Length let res = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked len1 let inputChunks = createPartitionsUpTo array1.Length array1 diff --git a/src/FSharp.Core/array.fsi b/src/FSharp.Core/array.fsi index 866016908d5..8bca1cc435d 100644 --- a/src/FSharp.Core/array.fsi +++ b/src/FSharp.Core/array.fsi @@ -3456,14 +3456,14 @@ module Array = val zip: array1:'T1[] -> array2:'T2[] -> ('T1 * 'T2)[] /// Returns a new collection containing only the elements of the collection - /// for which the given predicate returns "true". + /// for which the given predicate returns true. /// /// The function to test the input elements. /// The input array. /// /// An array containing the elements for which the given predicate returns true. /// - /// Thrown when the input array is null. + /// Thrown when the input array is null. /// /// ///