首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >以相同的方式混洗两个列表

以相同的方式混洗两个列表
EN

Stack Overflow用户
提问于 2012-03-15 07:09:14
回答 3查看 1.7K关注 0票数 1

我想混洗两个列表,使它们以相同的方式混洗(假设我有一个方法Shuffle(List list)可以混洗一个列表。

代码语言:javascript
复制
List<ObjX> listA = new List<ObjX>() { A, B, C, D };
List<ObjX> listB = new List<ObjX>() { W, X, Y, Z };
ShuffleTwoLists(listA , listB )

结果:

A: C,B,D,A

B: Y,X,Z,W

有没有在C#中实现ShuffleTwoLists(listA,listB)的快速方法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-15 07:12:57

选项1:压缩、随机播放、解压缩

为了扩展Marcelo的评论,假设你不介意创建新的列表,而不是打乱现有的列表:

代码语言:javascript
复制
var zipped = listA.Zip(listB, (a, b) => new { a, b } ).ToList();
Shuffle(zipped);
var newListA = zipped.Select(pair => pair.a).ToList();
var newListB = zipped.Select(pair => pair.b).ToList();

选项2:混洗索引

要用代码扩展MAK的答案:

代码语言:javascript
复制
var indexes = Enumerable.Range(0, listA.Count).ToList();
Shuffle(indexes);
var newListA = indexes.Select(index => listA[index]).ToList();
var newListB = indexes.Select(index => listB[index]).ToList();

当然,这两种方法都可以改变原始列表,但需要做更多的工作。

选项3:使用相同的随机种子打乱两个列表

就我个人而言,我喜欢将Random (或其他任何东西)传递给需要它们的方法/类,而不是创建新的方法/类。所以我会给我的Shuffle一个Random参数。它避免了各种问题,并且很好地表达了依赖关系。您可以通过创建两个具有相同种子的Random实例来利用这一点:

代码语言:javascript
复制
int seed = existingRandom.Next();
Shuffle(listA, new Random(seed));
Shuffle(listB, new Random(seed));

假设Shuffle在给定相同的随机数序列时做了同样的事情,这将以相同的方式对两个列表进行混洗。

票数 9
EN

Stack Overflow用户

发布于 2012-03-15 07:19:42

Jon的所有技术都很好。另一种技术是:

代码语言:javascript
复制
class PermutedList<T> 
{
    private readonly IList<T> underlying;
    private readonly IList<int> permutation;
    public T this[int i]
    {
        get { return underlying[permutation[i]]; }
    }
    ...

也就是说,在底层列表周围创建一个包装类。通过打乱一个从0到n-1的数组来进行排列。如果您将相同的排列数组应用于两个不同的列表,那么您将得到两个不同列表的相同“洗牌”。讲得通?

票数 5
EN

Stack Overflow用户

发布于 2012-03-15 07:12:17

获取一个新的in列表,它的内容都是[0, length of A and B)中的数字。它们与列表中元素的索引相对应。打乱这份清单。现在,使用随机排列的索引排列两个原始列表。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9711708

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档