我有List<Fruit>
,
public class Fruit
{
public string Name { get; set; }
public string Type { get; set; }
}
并且上面的列表包含两种类型的30个Fruit对象:Apple
和Orange
。 20个苹果和10个橙子。
List<Fruit> fruits = new List<Fruit>();
fruits.Add(new Fruit(){ Name = "Red Delicious", Type = "Apple" });
fruits.Add(new Fruit(){ Name = "Granny Smith", Type = "Apple" });
fruits.Add(new Fruit(){ Name = "Sour Granny", Type = "Orange" });
fruits.Add(new Fruit(){ Name = "Delicious Yummy", Type = "Orange" });
.....
如何获得10个随机水果的清单(来自30个水果的篮子),但应该有3个橙子和7个苹果?
答案 0 :(得分:12)
您可以使用LINQ和Guid
或Random
进行随机选择:
var apples = fruits.
Where( f => f.Type == "Apple" ). //choose only from apples
OrderBy( f => Guid.NewGuid() ). //order randomly
Take( 7 ). //take 7 apples
ToList();
同样适用于oranges
,仅使用"Orange"
代替"Apple"
而使用3代替7。
OrderBy
按给定条件对可枚举进行排序。因为Guid.NewGuid()
返回随机唯一标识符,结果是项目是随机排序的。然后,当我们应用Take( n )
时,它会以此随机顺序排列n
个第一项。
注意您可以创建Guid
的实例,并使用Random
作为f => random.NextDouble()
表达式,而不是OrderBy
。这可能是一个更安全的解决方案,因为Guid.NewGuid()
不保证是随机的,只是唯一的。
答案 1 :(得分:5)
首先,在苹果和橘子之间分开,所以你会有
var apples = basket.Where(f => f.Type == "Apple");
var oranges = basket.Where(f => f.Type == "Orange");
现在,为了获得随机数量的元素而不重复两个列表,您可以使用以下内容:
var random = new Random();
var numOfElements = 7; // Replace this with the number you want
apples.OrderBy(x => random.Next()).Take(numOfElements).ToList();
最后,结合你得到的两个清单。
答案 2 :(得分:5)
你可以洗一次,然后剥掉苹果和橘子 对于每种水果,它会比随机效率更高一些,但在短名单上没有太大的区别
public static void TestFruit()
{
List<Fruit> fruits = new List<Fruit>();
fruits.Add(new Fruit("01", "orange")); fruits.Add(new Fruit("02", "orange"));
fruits.Add(new Fruit("03", "orange")); fruits.Add(new Fruit("04", "orange"));
fruits.Add(new Fruit("05", "orange")); fruits.Add(new Fruit("06", "orange"));
fruits.Add(new Fruit("07", "orange")); fruits.Add(new Fruit("08", "orange"));
fruits.Add(new Fruit("09", "orange")); fruits.Add(new Fruit("10", "orange"));
fruits.Add(new Fruit("01", "apple")); fruits.Add(new Fruit("02", "apple"));
fruits.Add(new Fruit("03", "apple")); fruits.Add(new Fruit("04", "apple"));
fruits.Add(new Fruit("05", "apple")); fruits.Add(new Fruit("06", "apple"));
fruits.Add(new Fruit("07", "apple")); fruits.Add(new Fruit("08", "apple"));
fruits.Add(new Fruit("09", "apple")); fruits.Add(new Fruit("10", "apple"));
fruits.Add(new Fruit("11", "apple")); fruits.Add(new Fruit("12", "apple"));
fruits.Add(new Fruit("13", "apple")); fruits.Add(new Fruit("14", "apple"));
fruits.Add(new Fruit("15", "apple")); fruits.Add(new Fruit("16", "apple"));
fruits.Add(new Fruit("17", "apple")); fruits.Add(new Fruit("18", "apple"));
fruits.Add(new Fruit("19", "apple")); fruits.Add(new Fruit("20", "apple"));
Shuffle<Fruit>(fruits);
List<Fruit> randomFruits = fruits.Where(x => x.Type == "apple").Take(7).ToList();
randomFruits.AddRange(fruits.Where(x => x.Type == "orange").Take(3));
foreach (Fruit f in randomFruits)
{
Debug.WriteLine("Name {0} Type {1}", f.Name, f.Type);
}
Debug.WriteLine("");
}
public static void Shuffle<T>(List<T> list)
{ // FisherYates
for (int i = list.Count - 1; i >= 1; i--)
{
int j = rand.Next(i + 1);
if (j != i)
{ // exchange values
T curVal = list[i];
list[i] = list[j];
list[j] = curVal;
}
}
}
public class Fruit
{
public string Name { get; set; }
public string Type { get; set; }
public Fruit(string name, string type)
{
Name = name;
Type = type;
}
}