我的输入看起来像这样:
A 1 2 C,D
A 2 3 C,E
B 4 5 F
A 6 7
A 7 8 D
A 9 10 E
我将它存储在我的模型类中:
public class Item {
public String Name {get;set;}
public int Start {get;set;}
public int End {get;set;}
public List<string> Orders {get;set;}
}
如果项目具有相同的名称,我尝试使用Linq合并所有后续项目,并生成一个新项目,该项目具有组中第一项的起始值,组中最后一项的结束值以及所有订单列表的联合。它应该是这样的:
A 1 3 C,D,E
B 4 5 F
A 6 10 D, E
我尝试了以下Linq语句,然而,它将所有As和B组合在一起,而不管其间是否还有其他项目。我需要改变什么?订单清单的联合也缺失了。
var groups = items.GroupBy(i => i.Name).ToList();
foreach (var group in groups)
{
result.Add(new Item {
Start = group.First().Start,
End = group.Last().End,
Name = group.First().Name });
}
答案 0 :(得分:2)
使用经典循环:
var List<List<Item>> groups = new List<List<Item>>()
var currentGroup = new List<Item> { items.First() };
int i = 0;
foreach(var item in items.Skip(1))
{
if(currentGroup.First().Name != item.Name)
{
groups.Add(currentGroup);
currentGroup = new List<Item> { item };
}
else
{
currentGroup.Add(item);
if(i == items.Count - 2)
groups.Add(currentGroup);
}
i++;
}
现在,您可以通过迭代groups
- 列表来继续您的代码。
答案 1 :(得分:2)
也许不是最好或最快的方式,但我感到无聊:
int groupID = -1;
var result = items.Select((item, index) =>
{
if (index == 0 || items[index - 1].Name != item.Name)
++groupID;
return new { group = groupID, item = item };
}).GroupBy(item => item.group).Select(group =>
{
Item item = new Item();
var first = group.First().item;
var last = group.Last().item;
item.Name = first.Name;
item.Start = first.Start;
item.End = last.End;
item.Orders = group.SelectMany(g => g.item.Orders).Distinct().ToList();
return item;
});
变量items
应该是您的输入集合,如List<Item>
。结果将存储在result
中。这是IEnumerable<Item>
,但您可以根据需要添加.ToList()
或.ToArray()
,将其转换为List<Item>
或Item[]
。
结果将包含新创建的项目。我故意这样做是为了不弄乱输入数据。
这里的技巧是使用局部变量作为组ID。如果它是第一个项目或最后一个项目具有不同的名称,则会增加。然后我们按组ID进行分组,其余的代码将只创建项目。 SelectMany
方法将加入整个组中的所有Orders
- 值,Distinct
将删除所有重复项。
答案 2 :(得分:0)
Linq没有这样做。我只是使用更简单的方法玩了一下。但它给出了你想要的相同结果。
Could not create Appender