首页 > 解决方案 > 如何按规则拆分数组块?

问题描述

我可以将数组拆分成更小的块。

public class Item{
    public string Name {get; set;}  
    public bool IsUnique {get;set;} 
}

public static void Main()
{
    Random r = new Random();

    var source = new[] { 
        new Item { Name = "Item-1", IsUnique = true},
        new Item { Name = "Item-2", IsUnique = true},
        new Item { Name = "Item-3", IsUnique = true},
        new Item { Name = "Item-4"},
        new Item { Name = "Item-5"},
        new Item { Name = "Item-6"},
        new Item { Name = "Item-7"},
        new Item { Name = "Item-8"},
        new Item { Name = "Item-9"} 
    };

    var chunkSize = 3;

    var result = source         
        .OrderBy(a => r.Next())
        .Select((x, i) => new { Index = i, Item = x })          
        .GroupBy(s => s.Index / chunkSize)
        .Select(g => g.ToList())
        .ToList();

    foreach(var item in result)
    {
        Console.WriteLine("Chunk: "+ (result.IndexOf(item)+1));
        Console.WriteLine("-----------------------------------");
        foreach(var x in item)
        {               
            Console.WriteLine(x.Item.Name);
        }
        Console.WriteLine();
    }
}

结果是这样的:

Chunk: 1
-----------------------------------
Item-2
Item-3
Item-8

Chunk: 2
-----------------------------------
Item-5
Item-9
Item-7

Chunk: 3
-----------------------------------
Item-6
Item-4
Item-1

但是如果IsUniquer一个项目的属性是true,它们就不能在同一个块中。例如上面,Chunk-1包含item-2item-3

我可以使用 linq 做到这一点吗?

更新:

如果块大小为 3,则只有 3 个项目可能是 IsUnique=true。

标签: c#linq

解决方案


将你的source数组分成两组:那些是唯一的和休息的。然后遍历集合中的每个元素uniquechunkSize - 1nonUnique集合中获取。看一下这段代码:

var unique = source.Where(x => x.IsUnique);
var nonUnique = source.Where(x => !x.IsUnique)
    .OrderBy(x => r.Next())
    .ToList();

var result = unique.Aggregate(
    (list: new List<List<Item>>(), items: nonUnique),
    (c, n) =>
    {
        var next = c.items.Take(chunkSize - 1).ToList();
        next.Add(n);

        c.items.RemoveRange(0, chunkSize - 1);
        c.list.Add(next.OrderBy(x => r.Next()).ToList());
        return (c.list, c.items);
    }).list;

推荐阅读