FluentRandomPicker 3.2.0

.NET Standard 2.0
Install-Package FluentRandomPicker -Version 3.2.0
dotnet add package FluentRandomPicker --version 3.2.0
<PackageReference Include="FluentRandomPicker" Version="3.2.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add FluentRandomPicker --version 3.2.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: FluentRandomPicker, 3.2.0"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install FluentRandomPicker as a Cake Addin
#addin nuget:?package=FluentRandomPicker&version=3.2.0

// Install FluentRandomPicker as a Cake Tool
#tool nuget:?package=FluentRandomPicker&version=3.2.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

Fluent Random Picker

Fluent Random Picker

Fluent Random Picker is a nice, performant fluent way to pick random values. Probabilities can be specified, values can be weighted.

Build status License MIT Code coverage Nuget version NuGet downloads

Compatibility

Fluent Random Picker uses .Net Standard 2.0. That means, it can be used in projects with the following target frameworks:

  • ✔️ .Net 6
  • ✔️ .Net 5
  • ✔️ .Net Core 3.X
  • ✔️ .Net Core 2.X
  • ❌ .Net Core 1.X
  • ✔️ .Net Standard 2.1
  • ✔️ .Net Standard 2.0
  • ❌ .Net Standard 1.X
  • ✔️ .Net Framework 4.8
  • ✔️ .Net Framework 4.7.2
  • ❌ .Net Framework 4.6.X

Getting started

Install the nuget package (https://www.nuget.org/packages/FluentRandomPicker/)

Add the using directive:

using FluentRandomPicker;

Begin with Out.Of() (see the examples).

Out.Of()...

Examples

The easiest example

var randomNumber = Out.Of().Value(5).AndValue(6).PickOne();
// randomNumber is 5 or 6 with equal probability.

Specifying percentages

var randomChar = Out.Of()
                  .Value('a').WithPercentage(70)
                  .AndValue('b').WithPercentage(30)
                  .PickOne();
// or
var randomChar = Out.Of().Values(new List<char> { 'a', 'b' })
                  .WithPercentages(70, 30)
                  .PickOne();
// or
var randomChar = Out.Of().Values(new List<char> { 'a', 'b' })
                  .WithPercentages(new List<int> { 70, 30 })
                  .PickOne();
// randomChar is 'a' with a probability of 70 % and 'b' with a probability of 30 %.

Specifying weights

var randomString = Out.Of()
                  .Value("hello").WithWeight(2)
                  .AndValue("world").WithWeight(3)
                  .PickOne();
// or
var randomChar = Out.Of().Values(new HashSet<string> { "hello", "world" })
                  .WithWeights(2, 3)
                  .PickOne();
// or
var randomChar = Out.Of().Values(new HashSet<string> { "hello", "world" })
                  .WithWeights(new List<int> { 2, 3 })
                  .PickOne();
// randomString is "hello" or "world", but the probability for "world" is 1.5 times as high.

Picking multiple values

var randomInts = Out.Of()
                  .Value(1).WithPercentage(80)
                  .AndValue(10).WithPercentage(10)
                  .AndValue(100).WithPercentage(5)
                  .AndValue(1000).WithPercentage(5)
                  .Pick(5);
// randomInts can be [1, 1, 1, 1, 1] with a higher probability or [1, 1, 100, 10, 1]
// or even [1000, 1000, 1000, 1000, 1000] with a very small probability.

Picking distinct values

var randomInts = Out.Of()
                  .Values(new List<int> { 1, 10, 100, 1000 })
                  .WithPercentages(70, 15, 10, 5)
                  .PickDistinct(2);
// randomInts can be [1, 10], [1, 100], [1, 1000] ... but not [1, 1], [10, 10], ...

Omitting percentages or weights

var randomChar = Out.Of()
                  .Value('a').WithPercentage(80)
                  .AndValue('b') // no percentage
                  .AndValue('c') // no percentage
                  .PickOne();
// The missing percentages to reach 100% are equally distributed on the values without specified percentages.
// Attention! The missing percentages to reach 100% must be divisible without remainder through the number of values without percentages.
// randomChar is 'a' with a probability of 80% or 'b' or 'c' with a probability of each 10%.
var randomString = Out.Of()
                  .Value("hello").WithWeight(4)
                  .AndValue("world") // no weight
                  .PickOne();
// The default weight is 1.
// randomString is "hello" with a probability of 80% (4 of 5) and "world" with a probability of 20% (1 of 5).

Specifying the returned type explicitly

var operation = Out.Of<Func<long, long>>()
                .Value(i => i + 2)
                .AndValue(i => i * 2)
                .AndValue(i => (long)Math.Pow(i, 2))
                .AndValue(i => (long)Math.Pow(i, i))
                .PickOne();

var result = operation(10);
// result equals 10 + 2 or 10 * 2 or 10^2 or 10^10. 

Advanced

Specifying a seed

var seed = 1234567;

var value1 = Out.Of(seed).Values(new[] { 1, 2, 3, 4 }).PickOne();
var value2 = Out.Of(seed).Values(new[] { 1, 2, 3, 4 }).PickOne();
// value1 and value2 are always equal.

Using a different random number generator

The default random number generator uses System.Random.

Alternative: Using a cryptographically secure implementation that uses System.Security.Cryptography.RandomNumberGenerator:

var secureRng = new FluentRandomPicker.Random.SecureRandomNumberGenerator();
var value = Out.Of(secureRng).Values(new[] { 1, 2, 3, 4 }).PickOne();

Alternative: Using own implementation:

public class MyOwnRandomNumberGenerator : IRandomNumberGenerator
{
    public double NextDouble()
    {
        // ...
    }

    public int NextInt()
    {
        // ...
    }

    public int NextInt(int n)
    {
        // ...
    }

    public int NextInt(int min, int max)
    {
        // ...
    }
}

var myRng = new MyOwnRandomNumberGenerator();
var value = Out.Of(myRng).Values(new[] { 1, 2, 3, 4 }).PickOne();
// value gets picked via a specified random number generator.

Migration to version 3

The namespace was changed to match coding conventions. Please replace:

using Fluent_Random_Picker;

with

using FluentRandomPicker;

Some method parameter identifiers do also have changed to match the coding conventions of Microsoft.

Migration to version 2

The params array is not supported anymore for the Values method. Please replace

Out.Of().Values(1, 2, 3)...

with

Out.Of().Value(1).AndValue(2).AndValue(3)...

or

Out.Of().Values(new List<int>{ 1, 2, 3 })...

Reason: https://github.com/ndsvw/Fluent-Random-Picker/commit/da9af06bda215d0983e428072febed8f33577041

Product Versions
.NET net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows
.NET Core netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1
.NET Standard netstandard2.0 netstandard2.1
.NET Framework net461 net462 net463 net47 net471 net472 net48
MonoAndroid monoandroid
MonoMac monomac
MonoTouch monotouch
Tizen tizen40 tizen60
Xamarin.iOS xamarinios
Xamarin.Mac xamarinmac
Xamarin.TVOS xamarintvos
Xamarin.WatchOS xamarinwatchos
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.2.0 123 4/28/2022
3.1.0 2,309 11/27/2021
3.0.2 110 11/13/2021
3.0.1 174 8/7/2021
3.0.0 182 7/28/2021
2.1.0 262 7/10/2021
2.0.1 155 6/28/2021
2.0.0 249 6/26/2021
1.2.0 241 5/22/2021
1.1.1 133 5/15/2021
1.1.0 160 4/24/2021
1.0.4 143 4/17/2021
1.0.3 132 4/16/2021
1.0.2 151 4/15/2021
1.0.1 120 4/15/2021
1.0.0 138 4/15/2021

v 3.2.0
- Cleaned up targets (.Net standard) supports various targets.
- Improved implementation for when picking multiple distinct values.
v 3.1.0
- Implemented class SecureRandomNumberGenerator (secure implementation of IRandomNumberGenerator).
v 3.0.2
- Added .Net6 as compatibility to README file.
v 3.0.1
- Prevented arithmetic overflows when percentage sums / weights sums are too high.
v 3.0.0
- Changed namespace from Fluent_Random_Picker to FluentRandomPicker
- Allowed omitting percentages and weights. E.g. Out.Of().Value('a').WithWeight(2).AndValue('b').PickOne();
- Fixed bug: The shuffle algorithm was not working correctly.
- Improved documentation
- Renamed multiple interfaces, method parameters, ...
v 2.1.0
- Improved package generation process, used SourceLink, fixed version differences of dll, package, ...