我可以将数组拆分为较小的块。
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-2
和 item-3
。
我可以使用 linq 执行此操作吗?
更新:
如果区块大小为 3,则只有 3 个项目可能是 IsUnique=true。
将source
数组分成两组:那些唯一的项目和其余的项目。然后循环访问unique
集合中的每个元素,并从nonUnique
集合中获取chunkSize - 1
。看看你的代码:
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;