[英]How do I generate a rule for more than one option in Bogus?
I have a rule to select an option at random:我有一个随机选项 select 的规则:
.RuleFor(c=>field, x=>x.PickRandom("Option1", "Option2", "Option3", "Option4"))
With a default value, I can alter the probability of one of the items.使用默认值,我可以更改其中一项的概率。 I would like to set the probabilities of all four items.
我想设置所有四个项目的概率。 Option1 would be picked 50% of the time, Option2 would be picked 30%, then 15% for Option3, and 5% for Option4.
选项 1 的选择率为 50%,选项 2 的选择率为 30%,选项 3 为 15%,选项 4 为 5%。
I would like to use a WeightedRandom:我想使用WeightedRandom:
.RuleFor(c=>field, x=>PickWeightedRandom(valueArray, weightArray)
There is no such method as PickWeightedRandom, but WeightedRandom is a method in the Randomizer class.没有 PickWeightedRandom 这样的方法,但是 WeightedRandom 是 Randomizer class 中的一种方法。 How do I get the WeightedRandom to work?
如何让 WeightedRandom 工作?
EDIT: Maybe an extension method?编辑:也许是一种扩展方法?
The following seems to work:以下似乎有效:
void Main()
{
var items = new []{"kiwi", "orange", "cherry", "apple"};
var weights = new[]{0.1f, 0.1f, 0.2f, 0.6f};
var faveFaker = new Faker<Favorite>()
.RuleFor(x => x.Fruit, f => f.Random.WeightedRandom(items, weights));
faveFaker.Generate(10).Dump();
}
public class Favorite
{
public string Fruit {get;set;}
}
Of course, using C# extension methods are always an excellent way to extend Bogus to best suit your API needs:当然,使用 C# 扩展方法始终是扩展 Bogus 以最适合您的 API 需求的绝佳方式:
void Main()
{
var faveFaker = new Faker<Favorite>()
.RuleFor(x => x.Fruit, f => f.WeightedRandom( ("kiwi", 0.1f), ("orange", 0.1f),
("cherry", 0.2f), ("apple", 0.6f)) );
faveFaker.Generate(10).Dump();
}
public class Favorite
{
public string Fruit {get;set;}
}
public static class MyExtensionsForBogus
{
public static T WeightedRandom<T>(this Faker f, params (T item, float weight)[] items)
{
var weights = items.Select(i => i.weight).ToArray();
var choices = items.Select(i => i.item).ToArray();
return f.Random.WeightedRandom(choices, weights);
}
}
One answer is to pick the random string somewhere else, then use the => operator to point to the result.一个答案是在其他地方选择随机字符串,然后使用 => 运算符指向结果。
public static string PickAString(string[] items, float[] weights)
{
// hopefully all the weights will add up to 1. If not, this method may throw for array out of bounds.
// Also, it would be best if the number of items in each array is the same, to prevent out of bounds exception.
// generate a number from 0 to less than 1
double randomValue = random.NextDouble();
double weightSum = 0;
for (int i = 0; i < items.Length; i++)
{
weightSum += weights[i];
if (randomValue < weightSum)
return items[i];
}
return null; // if the weights don't add up.
}
.RuleFor(c => c.field, _ =>
{
return PickAString(values, weights);
})
This works, but it would be more elegant to add this to the library.这可行,但将其添加到库中会更优雅。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.