在这样的列表中:
var colors = new List<string>{"green", "red", "blue", "black","purple"};
我可以这样获得第一个值:
var color = colors.First(c => c.StartsWidth("b")); //This will return the string with "blue"
如果我想要一个与条件匹配的随机值,该怎么办?例如这样的事情:
Debug.log(colors.RandomFirst(c => c.StartsWidth("b"))) // Prints out black
Debug.log(colors.RandomFirst(c => c.StartsWidth("b"))) // Prints out black
Debug.log(colors.RandomFirst(c => c.StartsWidth("b"))) // Prints out blue
Debug.log(colors.RandomFirst(c => c.StartsWidth("b"))) // Prints out black
就像列表中有多个符合条件的条目一样,我想随机抽取其中之一。它(必须是)必须是内联解决方案。谢谢。
然后随机排序:
var rnd = new Random();
var color = colors.Where(c => c.StartsWith("b"))
.OrderBy(x => rnd.Next())
.First();
上面的代码为每个元素生成一个随机数,并根据该数字对结果进行排序。
如果只有两个符合条件的元素,您可能不会注意到随机结果。但是您可以尝试以下示例(使用下面的扩展方法):
var colors = Enumerable.Range(0, 100).Select(i => "b" + i);
var rnd = new Random();
for (int i = 0; i < 5; i++)
{
Console.WriteLine(colors.RandomFirst(x => x.StartsWith("b"), rnd));
}
输出:
b23
b73
b27
b11
b8
您可以通过以下方法创建扩展方法RandomFirst
:
public static class MyExtensions
{
public static T RandomFirst<T>(this IEnumerable<T> source, Func<T, bool> predicate,
Random rnd)
{
return source.Where(predicate).OrderBy(i => rnd.Next()).First();
}
}
用法:
var rnd = new Random();
var color1 = colors.RandomFirst(x => x.StartsWith("b"), rnd);
var color2 = colors.RandomFirst(x => x.StartsWith("b"), rnd);
var color3 = colors.RandomFirst(x => x.StartsWith("b"), rnd);
如果您担心性能,可以尝试以下优化方法(将大型列表的时间减少一半):
public static T RandomFirstOptimized<T>(this IEnumerable<T> source,
Func<T, bool> predicate, Random rnd)
{
var matching = source.Where(predicate);
int matchCount = matching.Count();
if (matchCount == 0)
matching.First(); // force the exception;
return matching.ElementAt(rnd.Next(0, matchCount));
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句