如何在没有下一个和上一个列表重复的情况下洗牌 List<List<string>>
How to shuffle List<List<string>> without next and previous list having duplicates
所以我有几个列表
List<List<string>> fruits = new List<List<string>>();
List<string> apple_small = new List<string>();
apple_small.Add("apple");
apple_small.Add("apple");
List<string> apple_medium = new List<string>();
apple_medium.Add("apple");
apple_medium.Add("apple");
apple_medium.Add("apple");
List<string> apple_big = new List<string>();
apple_big.Add("apple");
apple_big.Add("apple");
apple_big.Add("apple");
apple_big.Add("apple");
List<string> orange_small = new List<string>();
orange_small.Add("orange");
orange_small.Add("orange");
List<string> orange_medium = new List<string>();
orange_medium.Add("orange");
orange_medium.Add("orange");
orange_medium.Add("orange");
List<string> orange_big = new List<string>();
orange_big.Add("orange");
orange_big.Add("orange");
orange_big.Add("orange");
orange_big.Add("orange");
List<string> grape_small = new List<string>();
grape_small.Add("grape");
grape_small.Add("grape");
List<string> grape_medium = new List<string>();
grape_medium.Add("grape");
grape_medium.Add("grape");
grape_medium.Add("grape");
List<string> grape_big = new List<string>();
grape_big.Add("grape");
grape_big.Add("grape");
grape_big.Add("grape");
grape_big.Add("grape");
fruits.Add(apple_small);
fruits.Add(apple_medium);
fruits.Add(apple_big);
fruits.Add(orange_small);
fruits.Add(orange_medium);
fruits.Add(orange_big);
fruits.Add(grape_small);
fruits.Add(grape_medium);
fruits.Add(grape_big);
如果列表是 "apples",它包含的唯一值是 "apples",但列表中的元素数量不同。我怎样才能打乱这个,这样最终的结果就是这样的。
orange_small
apple_small
orange_big
grape_medium
apple_big
grape_small
orange_medium
apple_medium
grape_big
或下一个和上一个列表不是来自同一个水果的任何其他可行组合?
每次列表包含不同的水果和里面的水果数量。因此,如果我们将列表视为一个数组。
[A1,A2,A3,B1,B2,B3,C1,C2,C3] shuffle 可以是任何类型,无需重复下一个和上一个类型。 [A1,B1,C3,B2,C2,A2,C1,B1...]
在某些情况下,这些值不允许以不重复每个符号的方式对组合进行洗牌。
[A1,A2,A3,B1] 如果我有这样的列表,它应该是
[A1,B1,A2,B1,A3] 如果没有更多的洗牌选项,它应该能够重用一个列表。
是这样的吗?
public static List<List<string>> ShuffleList(List<List<string>> fruits)
{
var random = new Random();
var copy = fruits.ToList();
var shuffle = new List<List<string>>();
List<string> previous = null;
while (true)
{
var next = GetNext();
copy.Remove(next);
shuffle.Add(next);
previous = next;
if(!copy.Any()) break;
}
return shuffle;
List<string> GetNext()
{
if (previous is null)
{
return copy[random.Next(copy.Count)];
}
var otherFruits = copy.Where(list => list.Any(f => f != previous[0])).ToList();
if (otherFruits.Count == 0)
{
// start use duplicates if no more unique values
otherFruits = fruits.Where(list => list.Any(f => f != previous[0])).ToList();
}
return otherFruits[random.Next(otherFruits.Count)];
}
}
结果如下:
foreach (var list in ShuffleList(fruits))
{
Console.WriteLine($"{list.First()}: {list.Count}");
}
orange: 4
grape: 2
apple: 3
orange: 2
apple: 2
grape: 3
apple: 4
grape: 4
orange: 3
如果仅使用所有 "apples" 和一个 "orange",结果将重复:
apple: 4
orange: 2
apple: 2
orange: 2
apple: 3
所以我有几个列表
List<List<string>> fruits = new List<List<string>>();
List<string> apple_small = new List<string>();
apple_small.Add("apple");
apple_small.Add("apple");
List<string> apple_medium = new List<string>();
apple_medium.Add("apple");
apple_medium.Add("apple");
apple_medium.Add("apple");
List<string> apple_big = new List<string>();
apple_big.Add("apple");
apple_big.Add("apple");
apple_big.Add("apple");
apple_big.Add("apple");
List<string> orange_small = new List<string>();
orange_small.Add("orange");
orange_small.Add("orange");
List<string> orange_medium = new List<string>();
orange_medium.Add("orange");
orange_medium.Add("orange");
orange_medium.Add("orange");
List<string> orange_big = new List<string>();
orange_big.Add("orange");
orange_big.Add("orange");
orange_big.Add("orange");
orange_big.Add("orange");
List<string> grape_small = new List<string>();
grape_small.Add("grape");
grape_small.Add("grape");
List<string> grape_medium = new List<string>();
grape_medium.Add("grape");
grape_medium.Add("grape");
grape_medium.Add("grape");
List<string> grape_big = new List<string>();
grape_big.Add("grape");
grape_big.Add("grape");
grape_big.Add("grape");
grape_big.Add("grape");
fruits.Add(apple_small);
fruits.Add(apple_medium);
fruits.Add(apple_big);
fruits.Add(orange_small);
fruits.Add(orange_medium);
fruits.Add(orange_big);
fruits.Add(grape_small);
fruits.Add(grape_medium);
fruits.Add(grape_big);
如果列表是 "apples",它包含的唯一值是 "apples",但列表中的元素数量不同。我怎样才能打乱这个,这样最终的结果就是这样的。
orange_small
apple_small
orange_big
grape_medium
apple_big
grape_small
orange_medium
apple_medium
grape_big
或下一个和上一个列表不是来自同一个水果的任何其他可行组合?
每次列表包含不同的水果和里面的水果数量。因此,如果我们将列表视为一个数组。
[A1,A2,A3,B1,B2,B3,C1,C2,C3] shuffle 可以是任何类型,无需重复下一个和上一个类型。 [A1,B1,C3,B2,C2,A2,C1,B1...]
在某些情况下,这些值不允许以不重复每个符号的方式对组合进行洗牌。
[A1,A2,A3,B1] 如果我有这样的列表,它应该是
[A1,B1,A2,B1,A3] 如果没有更多的洗牌选项,它应该能够重用一个列表。
是这样的吗?
public static List<List<string>> ShuffleList(List<List<string>> fruits)
{
var random = new Random();
var copy = fruits.ToList();
var shuffle = new List<List<string>>();
List<string> previous = null;
while (true)
{
var next = GetNext();
copy.Remove(next);
shuffle.Add(next);
previous = next;
if(!copy.Any()) break;
}
return shuffle;
List<string> GetNext()
{
if (previous is null)
{
return copy[random.Next(copy.Count)];
}
var otherFruits = copy.Where(list => list.Any(f => f != previous[0])).ToList();
if (otherFruits.Count == 0)
{
// start use duplicates if no more unique values
otherFruits = fruits.Where(list => list.Any(f => f != previous[0])).ToList();
}
return otherFruits[random.Next(otherFruits.Count)];
}
}
结果如下:
foreach (var list in ShuffleList(fruits))
{
Console.WriteLine($"{list.First()}: {list.Count}");
}
orange: 4
grape: 2
apple: 3
orange: 2
apple: 2
grape: 3
apple: 4
grape: 4
orange: 3
如果仅使用所有 "apples" 和一个 "orange",结果将重复:
apple: 4
orange: 2
apple: 2
orange: 2
apple: 3