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

Commit58a48e1

Browse files
gdziadkiewiczKevinRansom
authored andcommitted
Add TryExactlyOne for array, list and seq. (dotnet#5804)
1 parent5ae8597 commit58a48e1

File tree

12 files changed

+134
-7
lines changed

12 files changed

+134
-7
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,12 @@ namespace Microsoft.FSharp.Collections
12431243
elif array.Length=0then invalidArg"array" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString
12441244
else invalidArg"array"(SR.GetString(SR.inputSequenceTooLong))
12451245

1246+
[<CompiledName("TryExactlyOne")>]
1247+
lettryExactlyOne(array:'T[])=
1248+
checkNonNull"array" array
1249+
if array.Length=1then Some array.[0]
1250+
else None
1251+
12461252
lettransposeArrays(array:'T[][])=
12471253
letlen= array.Length
12481254
if len=0then Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked0else

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,16 @@ namespace Microsoft.FSharp.Collections
243243
[<CompiledName("ExactlyOne")>]
244244
val exactlyOne:array:'T[]-> 'T
245245

246+
///<summary>Returns the only element of the array or <c>None</c> if array is empty or contains more than one element.</summary>
247+
///
248+
///<param name="array">The input array.</param>
249+
///
250+
///<returns>The only element of the array or None.</returns>
251+
///
252+
///<exception cref="System.ArgumentNullException">Thrown when the input array is null.</exception>
253+
[<CompiledName("TryExactlyOne")>]
254+
val tryExactlyOne:array:'T[]-> 'T option
255+
246256
///<summary>Returns a new list with the distinct elements of the input array which do not appear in the itemsToExclude sequence,
247257
///using generic hash and equality comparisons to compare values.</summary>
248258
///

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,12 @@ namespace Microsoft.FSharp.Collections
671671
|[]-> invalidArg"source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString
672672
|_-> invalidArg"source"(SR.GetString(SR.inputSequenceTooLong))
673673

674+
[<CompiledName("TryExactlyOne")>]
675+
lettryExactlyOne(list:list<_>)=
676+
match listwith
677+
|[x]-> Some x
678+
|_-> None
679+
674680
[<CompiledName("Transpose")>]
675681
lettranspose(lists:seq<'Tlist>)=
676682
checkNonNull"lists" lists

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ namespace Microsoft.FSharp.Collections
172172
[<CompiledName("ExactlyOne")>]
173173
val exactlyOne:list:'T list-> 'T
174174

175+
///<summary>Returns the only element of the list or <c>None</c> if it is empty or contains more than one element.</summary>
176+
///
177+
///<param name="list">The input list.</param>
178+
///
179+
///<returns>The only element of the list or None.</returns>
180+
[<CompiledName("TryExactlyOne")>]
181+
val tryExactlyOne:list:'T list-> 'T option
182+
175183
///<summary>Tests if any element of the list satisfies the given predicate.</summary>
176184
///
177185
///<remarks>The predicate is applied to the elements of the input list. If any application

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,19 @@ namespace Microsoft.FSharp.Collections
14211421
else
14221422
invalidArg"source" LanguagePrimitives.ErrorStrings.InputSequenceEmptyString
14231423

1424+
[<CompiledName("TryExactlyOne")>]
1425+
lettryExactlyOne(source:seq<_>)=
1426+
checkNonNull"source" source
1427+
use e= source.GetEnumerator()
1428+
if e.MoveNext()then
1429+
letv= e.Current
1430+
if e.MoveNext()then
1431+
None
1432+
else
1433+
Some v
1434+
else
1435+
None
1436+
14241437
[<CompiledName("Reverse")>]
14251438
letrev source=
14261439
checkNonNull"source" source

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,16 @@ namespace Microsoft.FSharp.Collections
558558
[<CompiledName("ExactlyOne")>]
559559
val exactlyOne:source:seq<'T>-> 'T
560560

561+
///<summary>Returns the only element of the sequence or <c>None</c> if sequence is empty or contains more than one element.</summary>
562+
///
563+
///<param name="source">The input sequence.</param>
564+
///
565+
///<returns>The only element of the sequence or None.</returns>
566+
///
567+
///<exception cref="System.ArgumentNullException">Thrown when the input sequence is null.</exception>
568+
[<CompiledName("TryExactlyOne")>]
569+
val tryExactlyOne:source:seq<'T>-> 'T option
570+
561571
///<summary>Returns true if the sequence contains no elements,false otherwise.</summary>
562572
///
563573
///<param name="source">The input sequence.</param>

‎tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ArrayModule.fs‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,24 @@ type ArrayModule() =
11861186
memberthis.``exactlyOne should fail on arrays with more than one element``()=
11871187
CheckThrowsArgumentException(fun()-> Array.exactlyOne[|"1";"2"|]|> ignore)
11881188

1189+
[<Test>]
1190+
memberthis.``tryExactlyOne should return the element from singleton arrays``()=
1191+
Assert.AreEqual(Some1, Array.tryExactlyOne[|1|])
1192+
Assert.AreEqual(Some"2", Array.tryExactlyOne[|"2"|])
1193+
()
1194+
1195+
[<Test>]
1196+
memberthis.``tryExactlyOne should return None on empty array``()=
1197+
Assert.AreEqual(None, Array.tryExactlyOne[||])
1198+
1199+
[<Test>]
1200+
memberthis.``tryExactlyOne should return None for arrays with more than one element``()=
1201+
Assert.AreEqual(None, Array.tryExactlyOne[|"1";"2"|])
1202+
1203+
[<Test>]
1204+
memberthis.``tryExactlyOne should fail on null array``()=
1205+
CheckThrowsArgumentNullException(fun()-> Array.tryExactlyOnenull|> ignore)
1206+
11891207
[<Test>]
11901208
memberthis.GroupBy()=
11911209
letfuncInt x= x%5

‎tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/CollectionModulesConsistency.fs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,18 @@ let ``exactlyOne is consistent`` () =
200200
smallerSizeCheck exactlyOne<string>
201201
smallerSizeCheck exactlyOne<NormalFloat>
202202

203+
lettryExactlyOne<'awhen'a:comparison>(xs:'a[])=
204+
lets= runAndCheckErrorType(fun()-> xs|> Seq.tryExactlyOne)
205+
letl= runAndCheckErrorType(fun()-> xs|> List.ofArray|> List.tryExactlyOne)
206+
leta= runAndCheckErrorType(fun()-> xs|> Array.tryExactlyOne)
207+
consistency"tryExactlyOne" s l a
208+
209+
[<Test>]
210+
let``tryExactlyOne is consistent``()=
211+
smallerSizeCheck tryExactlyOne<int>
212+
smallerSizeCheck tryExactlyOne<string>
213+
smallerSizeCheck tryExactlyOne<NormalFloat>
214+
203215
letexcept<'awhen'a:equality>(xs:'a[])(itemsToExclude:'a[])=
204216
lets= xs|> Seq.except itemsToExclude|> Seq.toArray
205217
letl= xs|> List.ofArray|> List.except itemsToExclude|> List.toArray

‎tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/ListModule.fs‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,20 @@ type ListModule() =
808808
memberthis.``exactlyOne should fail on lists with more than one element``()=
809809
CheckThrowsArgumentException(fun()-> List.exactlyOne["1";"2"]|> ignore)
810810

811+
[<Test>]
812+
memberthis.``tryExactlyOne should return the element from singleton lists``()=
813+
Assert.AreEqual(Some1, List.tryExactlyOne[1])
814+
Assert.AreEqual(Some"2", List.tryExactlyOne["2"])
815+
()
816+
817+
[<Test>]
818+
memberthis.``tryExactlyOne should return None for empty list``()=
819+
Assert.AreEqual(None, List.tryExactlyOne[])
820+
821+
[<Test>]
822+
memberthis.``tryExactlyOne should return None for lists with more than one element``()=
823+
Assert.AreEqual(None, List.tryExactlyOne["1";"2"])
824+
811825
[<Test>]
812826
memberthis.TryHead()=
813827
// integer List

‎tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Collections/SeqModule2.fs‎

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,17 +139,41 @@ type SeqModule2() =
139139
// Empty Seq
140140
letemptySeq= Seq.empty
141141
CheckThrowsArgumentException(fun()-> Seq.exactlyOne emptySeq)
142-
142+
143143
// non-singleton Seq
144+
letnonSingletonSeq=[0..1]
145+
CheckThrowsArgumentException(fun()-> Seq.exactlyOne nonSingletonSeq|> ignore)
146+
147+
// null Seq
148+
letnullSeq:seq<'a>=null
149+
CheckThrowsArgumentNullException(fun()-> Seq.exactlyOne nullSeq)
150+
()
151+
152+
[<Test>]
153+
memberthis.TryExactlyOne()=
154+
letIntSeq=
155+
seq{for iin7..7do
156+
yield i}
157+
158+
Assert.AreEqual(Some7, Seq.tryExactlyOne IntSeq)
159+
160+
// string Seq
161+
letstrSeq= seq["second"]
162+
Assert.AreEqual(Some"second", Seq.tryExactlyOne strSeq)
163+
164+
// Empty Seq
144165
letemptySeq= Seq.empty
145-
CheckThrowsArgumentException(fun()-> Seq.exactlyOne[0..1]|> ignore)
146-
166+
Assert.AreEqual(None, Seq.tryExactlyOne emptySeq)
167+
168+
// non-singleton Seq
169+
letnonSingletonSeq=[0..1]
170+
Assert.AreEqual(None, Seq.tryExactlyOne nonSingletonSeq)
171+
147172
// null Seq
148173
letnullSeq:seq<'a>=null
149-
CheckThrowsArgumentNullException(fun()->Seq.exactlyOne nullSeq)
150-
()
151-
152-
174+
CheckThrowsArgumentNullException(fun()-> Seq.tryExactlyOne nullSeq|> ignore)
175+
()
176+
153177
[<Test>]
154178
memberthis.Init()=
155179

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp