在C#中以相同的顺序随机化两个List <string> </string>

时间:2015-03-10 20:52:30

标签: c# .net list

我有两个字符串列表enen1

List<string> en = new List<string>(new string[] { "horse", "cat", "dog", "milk", "honey"});
List<string> en1 = new List<string>(new string[] { "horse1", "cat2", "dog3", "milk4", "honey5" });

我想让他们的内容“随机播放”并将这些未完成的内容放到新的两个列表中。 但我也希望它们随机化,因此随机化后的列表仍然是

en[0] == en1[0]

随机化后的随机内容

{ "cat", "horse", "honey", "milk", "dog"}
{ "cat2", "horse1", "honey5", "milk4", "dog3"}

5 个答案:

答案 0 :(得分:4)

第三种显而易见的方式:

随机播放整数列表0, 1, ... , Count-1并将此列表用作原始列表的索引。

<小时/> 的修改

这就是这一行(对于user38 ......):

List<int> shuffeledIndex = new List<int>();
for(int i = 0; i < en.Count; i++) shuffeledIndex.Add(i);
shuffeledIndex.Shuffle();  // Assume this exists

enshuffeled = en[shuffeledIndex[i]];  // instead en[i]
en1shuffeled = en1[shuffeledIndex[i]]; 

答案 1 :(得分:3)

两种显而易见的方式:

  • 采用普通的随机播放方法,并将其更改为同时修改两个列表
  • 将两个列表转换为单个联合列表,将其重新排列,然后再将它们拆分

第二个对我来说听起来更干净。你可以使用类似的东西:

var joined = en.Zip(en1, (x, y) => new { x, y }).ToList();
var shuffled = joined.Shuffle(); // Assume this exists
en = shuffled.Select(pair => pair.x).ToList();
en1 = shuffled.Select(pair => pair.y).ToList();

答案 2 :(得分:3)

添加Jon Skeet的答案,一个很好的方法来进行改组是OrderBy(x => Guid.NewGuid())所以代码看起来像

var joined = en.Zip(en1, (x, y) => new { x, y });
var shuffled = joined.OrderBy(x => Guid.NewGuid()).ToList(); 
en = shuffled.Select(pair => pair.x).ToList();
en1 = shuffled.Select(pair => pair.y).ToList();

答案 3 :(得分:0)

嗯,我认为@Jon Skeet的答案比我的好(因为我只知道关于C#的基础知识,可能还有其他一些原因......:P),但是你可以用某些东西手动洗牌像这样:

for(int i=0;i<en.Count;i++) {
    int remainingCount = en.Count - 1;
    int exchangeIndex = i + (new Random()).nextInt(0, remainingCount);
    swap(en, i, exchangeIndex);
    swap(en1, i, exchangeIndex);
}

当然你需要写一个像swap(List<string> list, int indexA, int indexB)这样的交换函数:

string tmp = list[indexA];
list[indexA] = list[indexB];
list[indexB] = tmp;

答案 4 :(得分:0)

您可以先使用Zip函数将两个列表合并为一个:

var zipped = en.Zip(en1, (first, second) => new { first, second }).ToList();

然后你需要一个洗牌功能来洗牌。您可以在扩展方法中使用Fisher–Yates shuffle

public static void FisherYatesShuffle<T>(this IList<T> list)  
{  
    var rnd = new Random();  
    var x = list.Count;  
    while (x > 1) {  
        x--;  
        var y = rnd.Next(x + 1);  
        T value = list[y];  
        list[y] = list[x];  
        list[x] = value;  
    }  
}

使用扩展方法:

var shuffled = zipped.FisherYatesShuffle();

现在,您可以将它们再次拆分为两个单独的列表:

en = shuffled.Select(combined => combined.x).ToList();
en1 = shuffled.Select(combined => combined.y).ToList();