我有一个List
CartItem
,其中一些具有相同的Name
属性。
我需要所有Name
属性都是唯一的。显而易见的事情是将它们组合成具有Quantity
属性>的单个项目。 1,但由于我不会进入的原因,我不能自由地这样做。我也不想通过在每个名称附加一个GUID来做丑陋,简单的事情。所以我想在Name
属性中附加一个像“(1/3)”这样的子字符串,但仅限于具有重复项的名称。已经是唯一的名字我想单独留下,所以没有人说“(1 of 1)”。
这是我正在谈论的单元测试。我正试图想出一个更好的方法来评论评论之间的界限:
class CartItem
{
public string Name { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
}
[TestMethod]
public void TestSOQuestion()
{
var exampleList = new List<CartItem>
{
new CartItem
{ Name="Same String", UnitPrice=10.00m, Quantity=1},
new CartItem
{ Name="Same String", UnitPrice=10.00m, Quantity=1},
new CartItem
{ Name="Other String", UnitPrice=14.99m, Quantity=1},
new CartItem
{ Name="Other String", UnitPrice=14.99m, Quantity=1},
new CartItem
{ Name="Other String", UnitPrice=14.99m, Quantity=1},
new CartItem
{ Name="Only One Of This", UnitPrice=29.99m, Quantity=1}
};
var expectedList = new List<CartItem>
{
new CartItem
{ Name="Same String (1 of 2)", UnitPrice=10.00m, Quantity=1},
new CartItem
{ Name="Same String (2 of 2)", UnitPrice=10.00m, Quantity=1},
new CartItem
{ Name="Other String (1 of 3)", UnitPrice=14.99m, Quantity=1},
new CartItem
{ Name="Other String (2 of 3)", UnitPrice=14.99m, Quantity=1},
new CartItem
{ Name="Other String (3 of 3)", UnitPrice=14.99m, Quantity=1},
new CartItem
{ Name="Only One Of This", UnitPrice=29.99m, Quantity=1}
};
//This is the best I can come up with:
var groups = exampleList.GroupBy(item => item.Name)
.Where(g => g.Count() > 1);
foreach (var group in groups)
{
int i = 1;
foreach (var item in group)
{
item.Name = item.Name + string.Format(
" ({0} of {1})", i++, group.Count());
}
}
//Is there a better way to do this?
for (int i = 0; i < expectedList.Count(); i++)
{
Assert.AreEqual(expectedList[i].Name, exampleList[i].Name);
}
}
答案 0 :(得分:2)
var result=exampleList.GroupBy(p=>p.Name).SelectMany(p=>p.Select((value,index)=> new CartItem()
{
Name = value.Name +
(p.Count() == 1?"": string.Format(" ({0} of {1})", index+1, p.Count())),
UnitPrice=value.UnitPrice,
Quantity=value.Quantity,
}
)).ToList();
答案 1 :(得分:0)
感谢RedHat的深思熟虑的答案。
以下是我最终使用的内容:
exampleList.GroupBy(item => item.Name)
.Where(g => g.Count() > 1).ToList().ForEach
(
group =>
{
foreach (var item in group
.Select((x, i) => new { val = x, idx = i + 1 }))
{
item.val.Name += string.Format
(
" ({0} of {1})", item.idx, group.Count()
);
}
}
);
我更喜欢将结果投射到新的List
中,而不是将其投影到新的Name
中
有选择地修改现有集合中的Name
属性。
由于实际数据集主要具有非重复Where(g => g.Count() > 1)
属性
哪个会被Cart
排除在外,
通过嵌套的foreach循环进行的迭代次数会减少。
而且,这个Dictionary
类被大大简化了
题;它实际上包含更多属性,包括a
Cart
个名称 - 值对。必须投射每个房产
结果将意味着与string Name
类更紧密的耦合。
如果我们将来要添加或修改属性,请使用此代码
也必须更新。
为了避免这种维护问题,这种方法只需要
存在{{1}}属性。