Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdc83c2c

Browse files
OkayX6latkin
authored andcommitted
Implement Array.groupBy, List.groupBy
commit e475a20abc745fa3ac66d4d8908cd64404399ec7Author: latkin <latkin@microsoft.com>Date: Wed Oct 22 18:26:16 2014 -0700 Expanding tests a bitcommit fd744ea93f4786136a3abe8a9372a701065dabaaAuthor: latkin <latkin@microsoft.com>Date: Wed Oct 22 18:25:34 2014 -0700 Add nullcheck to Array, convert List to recursive loop, remove TrimExcess callscommit e8e7da1b54eec111665318d86c059a7837da1227Merge:4b52be7 a592490Author: latkin <latkin@microsoft.com>Date: Wed Oct 22 16:41:45 2014 -0700 Merge branch 'add-groupby-function' ofhttps://git01.codeplex.com/forks/okayx6/visualfsharptools into PR Conflicts: src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs src/fsharp/FSharp.Core.Unittests/SurfaceArea.4.0.fs src/fsharp/FSharp.Core.Unittests/SurfaceArea.Portable.fs src/fsharp/FSharp.Core/array.fsi src/fsharp/FSharp.Core/list.fscommit a5924903af624d16212114eab704904635640c36Author: Denis Ok <denis.ok77@gmail.com>Date: Wed Aug 27 01:37:56 2014 +0200 Implemented suggested perf optimizationscommit 135eb498c6a4178570521f98fc16db9f001661ccAuthor: Denis Ok <denis.ok77@gmail.com>Date: Fri Aug 15 02:25:51 2014 +0200 Implement Array.groupBy & List.groupBy + tests
1 parent4b52be7 commitdc83c2c

File tree

8 files changed

+151
-0
lines changed

8 files changed

+151
-0
lines changed

‎src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,43 @@ type ArrayModule() =
10091009
memberthis.``exactlyOne should fail on arrays with more than one element``()=
10101010
CheckThrowsArgumentException(fun()-> Array.exactlyOne[|"1";"2"|]|> ignore)
10111011

1012+
[<Test>]
1013+
memberthis.GroupBy()=
1014+
letfuncInt x= x%5
1015+
1016+
letIntArray=[|0..9|]
1017+
1018+
letgroup_byInt= Array.groupBy funcInt IntArray
1019+
1020+
letexpectedIntArray=
1021+
[|for iin0..4-> i,[|i; i+5|]|]
1022+
1023+
if group_byInt<> expectedIntArraythen Assert.Fail()
1024+
1025+
// string array
1026+
letfuncStr(x:string)= x.Length
1027+
letstrArray=[|"l1ngth7";"length 8";"l2ngth7";"length 9"|]
1028+
1029+
letgroup_byStr= Array.groupBy funcStr strArray
1030+
letexpectedStrArray=
1031+
[|
1032+
7,[|"l1ngth7";"l2ngth7"|]
1033+
8,[|"length 8"|]
1034+
9,[|"length 9"|]
1035+
|]
1036+
1037+
if group_byStr<> expectedStrArraythen Assert.Fail()
1038+
1039+
// Empty array
1040+
letemptyArray=[||]
1041+
letgroup_byEmpty= Array.groupBy funcInt emptyArray
1042+
letexpectedEmptyArray=[||]
1043+
1044+
if emptyArray<> expectedEmptyArraythen Assert.Fail()
1045+
1046+
CheckThrowsArgumentNullException(fun()-> Array.groupBy funcInt(null: int array)|> ignore)
1047+
()
1048+
10121049
memberprivatethis.InitTester initInt initString=
10131050
// integer array
10141051
letresultInt:int[]= initInt3(fun x-> x+3)

‎src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Collections/ListModule.fs‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,42 @@ type ListModule() =
646646

647647
()
648648

649+
[<Test>]
650+
memberthis.GroupBy()=
651+
letfuncInt x= x%5
652+
653+
letIntList=[0..9]
654+
655+
letgroup_byInt= List.groupBy funcInt IntList
656+
657+
letexpectedIntList=
658+
[for iin0..4-> i,[i; i+5]]
659+
660+
Assert.AreEqual(expectedIntList, group_byInt)
661+
662+
// string list
663+
letfuncStr(x:string)= x.Length
664+
letstrList=["l1ngth7";"length 8";"l2ngth7";"length 9"]
665+
666+
letgroup_byStr= List.groupBy funcStr strList
667+
letexpectedStrList=
668+
[
669+
7,["l1ngth7";"l2ngth7"]
670+
8,["length 8"]
671+
9,["length 9"]
672+
]
673+
674+
Assert.AreEqual(expectedStrList, group_byStr)
675+
676+
// Empty list
677+
letemptyList=[]
678+
letgroup_byEmpty= List.groupBy funcInt emptyList
679+
letexpectedEmptyList=[]
680+
681+
Assert.AreEqual(expectedEmptyList, emptyList)
682+
683+
()
684+
649685
[<Test>]
650686
memberthis.Hd()=
651687
// integer List

‎src/fsharp/FSharp.Core.Unittests/SurfaceArea.4.0.fs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T,T][] Pairwise[T](T[])
120120
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[])
121121
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1[],T2[]] Unzip[T1,T2](System.Tuple`2[T1,T2][])
122122
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,System.Int32][] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
123+
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
123124
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
124125
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T[],T[]] SplitAt[T](Int32, T[])
125126
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`3[T1,T2,T3][] Zip3[T1,T2,T3](T1[], T2[], T3[])
@@ -296,6 +297,7 @@ Microsoft.FSharp.Collections.ListModule: Int32 GetHashCode()
296297
Microsoft.FSharp.Collections.ListModule: Int32 Length[T](Microsoft.FSharp.Collections.FSharpList`1[T])
297298
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T,T]] Pairwise[T](Microsoft.FSharp.Collections.FSharpList`1[T])
298299
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] Zip[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2])
300+
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.FSharpList`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T])
299301
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T])
300302
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[T1,T2,T3]] Zip3[T1,T2,T3](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2], Microsoft.FSharp.Collections.FSharpList`1[T3])
301303
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T])

‎src/fsharp/FSharp.Core.Unittests/SurfaceArea.Portable.fs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T,T][] Pairwise[T](T[])
114114
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1,T2][] Zip[T1,T2](T1[], T2[])
115115
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T1[],T2[]] Unzip[T1,T2](System.Tuple`2[T1,T2][])
116116
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,System.Int32][] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
117+
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[TKey,T[]][] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], T[])
117118
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T[],T[]] Partition[T](Microsoft.FSharp.Core.FSharpFunc`2[T,System.Boolean], T[])
118119
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`2[T[],T[]] SplitAt[T](Int32, T[])
119120
Microsoft.FSharp.Collections.ArrayModule: System.Tuple`3[T1,T2,T3][] Zip3[T1,T2,T3](T1[], T2[], T3[])
@@ -290,6 +291,7 @@ Microsoft.FSharp.Collections.ListModule: Int32 GetHashCode()
290291
Microsoft.FSharp.Collections.ListModule: Int32 Length[T](Microsoft.FSharp.Collections.FSharpList`1[T])
291292
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T,T]] Pairwise[T](Microsoft.FSharp.Collections.FSharpList`1[T])
292293
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[T1,T2]] Zip[T1,T2](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2])
294+
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,Microsoft.FSharp.Collections.FSharpList`1[T]]] GroupBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T])
293295
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`2[TKey,System.Int32]] CountBy[T,TKey](Microsoft.FSharp.Core.FSharpFunc`2[T,TKey], Microsoft.FSharp.Collections.FSharpList`1[T])
294296
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[System.Tuple`3[T1,T2,T3]] Zip3[T1,T2,T3](Microsoft.FSharp.Collections.FSharpList`1[T1], Microsoft.FSharp.Collections.FSharpList`1[T2], Microsoft.FSharp.Collections.FSharpList`1[T3])
295297
Microsoft.FSharp.Collections.ListModule: Microsoft.FSharp.Collections.FSharpList`1[TResult] Choose[T,TResult](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.FSharpOption`1[TResult]], Microsoft.FSharp.Collections.FSharpList`1[T])

‎src/fsharp/FSharp.Core/array.fs‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace Microsoft.FSharp.Collections
77
openSystem.Collections.Generic
88
openSystem.Diagnostics.CodeAnalysis
99
openMicrosoft.FSharp.Core
10+
openMicrosoft.FSharp.Core.CompilerServices
1011
openMicrosoft.FSharp.Collections
1112
openMicrosoft.FSharp.Core.Operators
1213
openMicrosoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
@@ -401,6 +402,32 @@ namespace Microsoft.FSharp.Collections
401402
let recloop i= i>= len1||(f.Invoke(array1.[i], array2.[i])&& loop(i+1))
402403
loop0
403404

405+
[<CompiledName("GroupBy")>]
406+
letgroupBy keyf(array:'T[])=
407+
checkNonNull"array" array
408+
letdict=new Dictionary<RuntimeHelpers.StructBox<'Key>,ResizeArray<'T>>(RuntimeHelpers.StructBox<'Key>.Comparer)
409+
410+
// Build the groupings
411+
for i=0to(array.Length-1)do
412+
letv= array.[i]
413+
letkey= RuntimeHelpers.StructBox(keyf v)
414+
letok,prev= dict.TryGetValue(key)
415+
if okthen
416+
prev.Add(v)
417+
else
418+
letprev=new ResizeArray<'T>(1)
419+
dict.[key]<- prev
420+
prev.Add(v)
421+
422+
// Return the array-of-arrays.
423+
letresult= Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked dict.Count
424+
let mutablei=0
425+
for groupin dictdo
426+
result.[i]<- group.Key.Value, group.Value.ToArray()
427+
i<- i+1
428+
429+
result
430+
404431
[<CompiledName("Pick")>]
405432
letpick f(array:_[])=
406433
checkNonNull"array" array

‎src/fsharp/FSharp.Core/array.fsi‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,17 @@ namespace Microsoft.FSharp.Collections
373373
[<CompiledName("Head")>]
374374
val head:array:'T[]-> 'T
375375

376+
///<summary>Applies a key-generating function to each element of an array and yields an array of
377+
///unique keys. Each unique key contains an array of all elements that match
378+
///to this key.</summary>
379+
///
380+
///<param name="projection">A function that transforms an element of the array into a comparable key.</param>
381+
///<param name="array">The input array.</param>
382+
///
383+
///<returns>The result array.</returns>
384+
[<CompiledName("GroupBy")>]
385+
val groupBy:projection:('T-> 'Key)->array:'T[]->('Key* 'T[])[]when 'Key:equality
386+
376387
///<summary>Creates an array given the dimension and a generator function to compute the elements.</summary>
377388
///<param name="count">The number of elements to initialize.</param>
378389
///<param name="initializer">The function to generate the initial values for each index.</param>

‎src/fsharp/FSharp.Core/list.fs‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,31 @@ namespace Microsoft.FSharp.Collections
393393
[<CompiledName("Where")>]
394394
letwhere f x= Microsoft.FSharp.Primitives.Basics.List.filter f x
395395

396+
[<CompiledName("GroupBy")>]
397+
letgroupBy keyf(list:'T list)=
398+
letdict=new Dictionary<Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.StructBox<'Key>,ResizeArray<'T>>(Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.StructBox<'Key>.Comparer)
399+
400+
// Build the groupings
401+
let recloop list=
402+
match listwith
403+
| v:: t->
404+
letkey= Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers.StructBox(keyf v)
405+
letok,prev= dict.TryGetValue(key)
406+
if okthen
407+
prev.Add(v)
408+
else
409+
letprev=new ResizeArray<'T>(1)
410+
dict.[key]<- prev
411+
prev.Add(v)
412+
loop t
413+
|_->()
414+
loop list
415+
416+
// Return the list-of-lists.
417+
dict
418+
|> Seq.map(fun group->(group.Key.Value, Seq.toList group.Value))
419+
|> Seq.toList
420+
396421
[<CompiledName("Partition")>]
397422
letpartition p x= Microsoft.FSharp.Primitives.Basics.List.partition p x
398423

‎src/fsharp/FSharp.Core/list.fsi‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,17 @@ namespace Microsoft.FSharp.Collections
284284
[<CompiledName("ForAll2")>]
285285
val forall2:predicate:('T1-> 'T2->bool)->list1:'T1 list->list2:'T2 list->bool
286286

287+
///<summary>Applies a key-generating function to each element of a list and yields a list of
288+
///unique keys. Each unique key contains a list of all elements that match
289+
///to this key.</summary>
290+
///
291+
///<param name="projection">A function that transforms an element of the list into a comparable key.</param>
292+
///<param name="list">The input list.</param>
293+
///
294+
///<returns>The result list.</returns>
295+
[<CompiledName("GroupBy")>]
296+
val groupBy:projection:('T-> 'Key)->list:'T list->('Key* 'T list)list when 'Key:equality
297+
287298
///<summary>Returns the first element of the list.</summary>
288299
///
289300
///<param name="list">The input list.</param>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp