基于groupby的列表中项目的随机顺序

时间:2015-06-03 12:47:44

标签: c# linq

我有一个对象列表。他们每个人都有一个距离财产。 我想要改组每组中的项目顺序。 例如: 如果10个元素的距离= 0,而20个元素的距离= 5,我必须将距离= 0的元素混洗,然后将距离= 5的元素混洗。 它不应该随距离= 0来改变距离= 0。

我一直在尝试使用Random和groupby做一些事情,但没有给我正确的结果。

任何人都可以向我展示一些亮点吗?

4 个答案:

答案 0 :(得分:2)

一旦你有一个方法来改变一个序列:

public static IEnumerable<T> Shuffle<T>(
    this IEnumerable<T> source, Random random)
{
    var list = source.ToList();
    for (int i = list.Count; i > 0; i--)
    {
        var index = random.Next(i);
        var temp = list[index];
        list[index] = list[i - 1];
        list[i - 1] = temp;
        yield return temp;
    }
}

您只需对项目进行分组,并将每个组投影到该组的随机播放版本:

var random = new Random();
var query = data.GroupBy(item => item.Distance)
    .SelectMany(group => group.Shuffle(random));

答案 1 :(得分:1)

示例Item类:

public class Item
{
    private static int index = 0;   // for test purposes

    public int Distance { get; set; }
    public object Data { get; set; }

    public Item(int distance)
    {
        this.Distance = distance;
        this.Data = ++index;
    }
}

代码:

List<Item> list= new List<Item>
{
    new Item(10),
    new Item(10),
    new Item(10),
    new Item(10),
    new Item(10),
    new Item(20),
    new Item(20),
    new Item(20),
};

Random rnd = new Random();
foreach (var group in from e in list
                      orderby rnd.NextDouble()
                      group e by e.Distance into g
                      orderby g.Key
                      select g)
{
    Console.WriteLine("Group with distance {0}", group.Key);
    foreach (var item in group)
    {
        Console.WriteLine("Item Distance={0}, Data={1}", item.Distance, item.Data);
    }
    Console.WriteLine("----");
}

结果:

Group with distance 10
Item Distance=10, Data=3
Item Distance=10, Data=1
Item Distance=10, Data=2
Item Distance=10, Data=5
Item Distance=10, Data=4
----
Group with distance 20
Item Distance=20, Data=7
Item Distance=20, Data=6
Item Distance=20, Data=8
----

答案 2 :(得分:1)

让我们说这是你的班级

public class Element
{
    public int Distance { get; set; }
    public string Name { get; set; }
}

你有这些元素

List<Element> myList = new List<Element>();
myList.Add(new Element() { Distance = 10, Name = "test1" });
myList.Add(new Element() { Distance = 10, Name = "test2" });
myList.Add(new Element() { Distance = 20, Name = "test3" });
myList.Add(new Element() { Distance = 20, Name = "test4" });

然后按距离对元素进行分组并对列表进行混洗,其中包含元素

Random rnd = new Random();
var Result = myList.GroupBy(r => r.Distance)
    .Select(x => new[] {
        new {
        Group =  x.Key, 
        Items =  x.Select(r => r.Name).OrderBy(_ => rnd.Next())
        }
    });

答案 3 :(得分:0)

可以简化@Servy示例:

BETWEEN