Skip to content

Commit d84d4fd

Browse files
authored
Add Random.GetItems (#319)
1 parent f614c61 commit d84d4fd

File tree

6 files changed

+143
-3
lines changed

6 files changed

+143
-3
lines changed

apiCount.include.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
**API count: 539**
1+
**API count: 542**

api_list.include.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@
293293

294294
#### Random
295295

296+
* `void GetItems<T>(Random, ReadOnlySpan<T>, Span<T>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.random.getitems#system-random-getitems-1(system-readonlyspan((-0))-system-span((-0))))
297+
* `T[] GetItems<T>(Random, ReadOnlySpan<T>, int)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.random.getitems#system-random-getitems-1(system-readonlyspan((-0))-system-int32))
298+
* `T[] GetItems<T>(Random, T[], int)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.random.getitems#system-random-getitems-1(-0()-system-int32))
296299
* `void NextBytes(Random, Span<byte>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.random.nextbytes#system-random-nextbytes(system-span((system-byte))))
297300
* `void Shuffle<T>(Random, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.random.nextbytes#system-random-nextbytes(system-span((system-byte))))
298301
* `void Shuffle<T>(Random, Span<T>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.random.nextbytes#system-random-nextbytes(system-span((system-byte))))

readme.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The package targets `netstandard2.0` and is designed to support the following ru
1212
* `net5.0`, `net6.0`, `net7.0`, `net8.0`, `net9.0`, `net10.0`
1313

1414

15-
**API count: 539**<!-- singleLineInclude: apiCount. path: /apiCount.include.md -->
15+
**API count: 542**<!-- singleLineInclude: apiCount. path: /apiCount.include.md -->
1616

1717

1818
**See [Milestones](../../milestones?state=closed) for release notes.**
@@ -767,6 +767,9 @@ The class `Polyfill` includes the following extension methods:
767767

768768
#### Random
769769

770+
* `void GetItems<T>(Random, ReadOnlySpan<T>, Span<T>)`
771+
* `T[] GetItems<T>(Random, ReadOnlySpan<T>, int)`
772+
* `T[] GetItems<T>(Random, T[], int)`
770773
* `void NextBytes(Random, Span<byte>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.random.nextbytes#system-random-nextbytes(system-span((system-byte))))
771774
* `void Shuffle<T>(Random, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.random.nextbytes#system-random-nextbytes(system-span((system-byte))))
772775
* `void Shuffle<T>(Random, Span<T>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.random.nextbytes#system-random-nextbytes(system-span((system-byte))))

src/Consume/Consume.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,17 @@ void Random_Methods()
476476
Span<byte> bufferSpan = new byte[10];
477477
random.NextBytes(bufferSpan);
478478
random.Shuffle(bufferSpan);
479+
480+
ReadOnlySpan<int> choicesSpan = [1, 2, 3, 4, 5];
481+
Span<int> destination = new int[10];
482+
random.GetItems(choicesSpan, destination);
483+
484+
var resultFromSpan = random.GetItems(choicesSpan, 10);
479485
#endif
486+
487+
int[] choicesArray = [1, 2, 3, 4, 5];
488+
var resultFromArray = random.GetItems(choicesArray, 10);
489+
480490
var bufferArray = new byte[10];
481491
random.Shuffle(bufferArray);
482492
}

src/Polyfill/Polyfill_Random.cs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,82 @@ namespace Polyfills;
77

88
static partial class Polyfill
99
{
10+
#if !NET8_0_OR_GREATER
11+
12+
#if FeatureMemory
13+
14+
/// <summary>
15+
/// Fills the elements of a specified span with items chosen at random from the provided set of choices.
16+
/// </summary>
17+
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.random.getitems#system-random-getitems-1(system-readonlyspan((-0))-system-span((-0)))
18+
public static void GetItems<T>(
19+
this Random target,
20+
ReadOnlySpan<T> choices,
21+
Span<T> destination)
22+
{
23+
if (choices.IsEmpty)
24+
{
25+
throw new ArgumentException("Choices cannot be empty.", nameof(choices));
26+
}
27+
28+
for (int i = 0; i < destination.Length; i++)
29+
{
30+
destination[i] = choices[target.Next(choices.Length)];
31+
}
32+
}
33+
34+
/// <summary>
35+
/// Creates an array populated with items chosen at random from the provided set of choices.
36+
/// </summary>
37+
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.random.getitems#system-random-getitems-1(system-readonlyspan((-0))-system-int32)
38+
public static T[] GetItems<T>(
39+
this Random target,
40+
ReadOnlySpan<T> choices,
41+
int length)
42+
{
43+
if (choices.IsEmpty)
44+
{
45+
throw new ArgumentException("Choices cannot be empty.", nameof(choices));
46+
}
47+
48+
T[] result = new T[length];
49+
for (int i = 0; i < length; i++)
50+
{
51+
result[i] = choices[target.Next(choices.Length)];
52+
}
53+
54+
return result;
55+
}
56+
57+
#endif
58+
59+
/// <summary>
60+
/// Creates an array populated with items chosen at random from the provided set of choices.
61+
/// </summary>
62+
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.random.getitems#system-random-getitems-1(-0()-system-int32)
63+
public static T[] GetItems<T>(
64+
this Random target,
65+
T[] choices,
66+
int length)
67+
{
68+
if (choices.Length == 0)
69+
{
70+
throw new ArgumentException("Choices cannot be null or empty.", nameof(choices));
71+
}
72+
73+
T[] result = new T[length];
74+
for (int i = 0; i < length; i++)
75+
{
76+
result[i] = choices[target.Next(choices.Length)];
77+
}
78+
79+
return result;
80+
}
81+
82+
#endif
83+
1084
#if (NETSTANDARD || NETFRAMEWORK || NETCOREAPP2_0) && FeatureMemory
85+
1186
/// <summary>
1287
/// Fills the elements of a specified span of bytes with random numbers.
1388
/// </summary>

src/Tests/PolyfillTests_Random.cs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,60 @@
11
partial class PolyfillTests
22
{
3+
34
#if FeatureMemory
5+
46
[Test]
57
public void RandomNextBytesSpan()
68
{
79
var random = new Random();
810
Span<byte> buffer = new byte[10];
911
random.NextBytes(buffer);
10-
Assert.IsTrue(buffer.ToArray().Any(b => b != 0));
12+
Assert.IsTrue(buffer.ToArray().Any(_ => _ != 0));
13+
}
14+
15+
[Test]
16+
public void RandomGetItems_ReadOnlySpan_Span()
17+
{
18+
var random = new Random();
19+
ReadOnlySpan<int> choices = [1, 2, 3, 4, 5];
20+
Span<int> destination = new int[10];
21+
random.GetItems(choices, destination);
22+
23+
Assert.IsTrue(destination.Length == 10);
24+
foreach (var item in destination)
25+
{
26+
Assert.IsTrue(choices.Contains(item));
27+
}
28+
}
29+
30+
[Test]
31+
public void RandomGetItems_ReadOnlySpan_Int()
32+
{
33+
var random = new Random();
34+
ReadOnlySpan<int> choices = [1, 2, 3, 4, 5];
35+
var length = 10;
36+
var result = random.GetItems(choices, length);
37+
38+
Assert.AreEqual(length, result.Length);
39+
foreach (var item in result)
40+
{
41+
Assert.Contains(item, choices.ToArray());
42+
}
43+
}
44+
45+
[Test]
46+
public void RandomGetItems_Array_Int()
47+
{
48+
var random = new Random();
49+
int[] choices = [1, 2, 3, 4, 5];
50+
var length = 10;
51+
var result = random.GetItems(choices, length);
52+
53+
Assert.AreEqual(length, result.Length);
54+
foreach (var item in result)
55+
{
56+
Assert.Contains(item, choices);
57+
}
1158
}
1259

1360
[Test]
@@ -19,7 +66,9 @@ public void RandomShuffleSpan()
1966
random.Shuffle(buffer);
2067
Assert.IsTrue(buffer.ToArray().Any(b => b != 0));
2168
}
69+
2270
#endif
71+
2372
[Test]
2473
public void RandomShuffleArray()
2574
{

0 commit comments

Comments
 (0)