0

我有一个List<Item>. 有Item属性Id和。此列表中有重复的项目。我需要得到一个新的,它只包含非重复的s和 in应该是它在 first 中重复的次数。我尝试了类似的东西NameAmountList<Item>ItemItemAmountList<Item>

            for (int i = 0; i < list.Count; i++)
            {
                for (int j = 0; j < list.Count; j++)
                {
                        if (list[i].Name == list[j].Name)
                        {
                            list.Remove(prod.Components[j]);
                            list[i].Amount++;
                        }
                }
            }

但是这个循环存在一些问题。我的大脑过热了。请帮忙。

4

5 回答 5

1

一个简单的 LINQ 查询可以让您获得唯一项目以及它们出现的次数:

var distinct = list.GroupBy(o => o.Name)
                   .Select(g => new { Count = g.Count(), Item = g.First() })
                   .ToList();

然后你可以修改每个项目的Amount重复数:

foreach (var row in distinct)
{
    row.Item.Amount = row.Count;
}

最后取回List<Item>不包含重复项且数量正确的 a:

var uniqueItems = distinct.Select(r => r.Item).ToList();

重要提示:上面的代码假定“重复”项彼此无法区分,但没有其他区别(例如,它不需要Item具有默认构造函数)。根据具体情况,可以将其写成更短的形式。

此外,该Amount物业在这里看起来很奇怪。由于重复项不保证其金额的总和,那么 的目的是Item.Amount什么?我会假设数量为 2 的重复项目应该导致一个数量为 4 的项目,但是您的代码没有这样做(我的代码遵循该领先)。

于 2013-02-20T10:45:17.767 回答
0

在我的头顶上(还没有测试过):

list.GroupBy(x => x.Name)
    .Select(x => new Item {
                            Name = x.Key,
                            Amount = x.Count()
                          })
    .ToList();

您尚未指定 Id 会发生什么,所以我忽略了它们。

(注意这会创建一个新列表,而不是修改原始列表)。

于 2013-02-20T10:44:43.973 回答
0

尝试这样的事情:

var groups = from item in items
             group item by item.Property
             into grouped
             select grouped;

var distinct = from g in groups
               let item = g.First()
               let amount = g.Count()
               select new Item {Property = item.Property, Amount = amount};

之后distinct包含IEnumerable<Item>原始项目列表中的数量。

于 2013-02-20T10:52:25.487 回答
0

假设您通过前两个属性ID和确定重复项Name

您可以实现一个IEqualityComparer<Item>并将其用于Enumerable.GroupBy

var itemAmounts = items.GroupBy(i => i, new Item())
    .Select(g => new Item { 
        ID = g.First().ID, 
        Name = g.First().Name, 
        Amount = g.Count()
    });

这是您的 Item 类,具有以下有意义的实现IEqualityComparer<Item>

class Item : IEqualityComparer<Item>
{
    public int ID;
    public string Name;
    public int Amount;

    public bool Equals(Item x, Item y)
    {
        if (x == null || y == null) return false;

        bool equals = x.ID == y.ID && x.Name == y.Name;
        return equals;
    }

    public int GetHashCode(Item obj)
    {
        if (obj == null) return int.MinValue;

        int hash = 19;
        hash = hash + obj.ID.GetHashCode();
        hash = hash + obj.Name.GetHashCode();
        return hash;
    }
}

您也可以覆盖Equalsand GetHasdhCodefrom object,那么您根本不需要自定义比较器GroupBy

var itemAmounts = items.GroupBy(i => i)
    .Select(g => new Item { 
        ID = g.First().ID, 
        Name = g.First().Name, 
        Amount = g.Count()
    });

您可以使用上面已经可用的方法:

public override bool Equals(object obj)
{
    Item item2 = obj as Item;
    if (item2 == null)
        return false;
    else
        return Equals(this, item2);
}

public override int GetHashCode()
{
    return GetHashCode(this);
}
于 2013-02-20T10:53:29.273 回答
0
foreach(var item in list)
{
    if(list.Count(e=>e.Id == item.Id && e.Name == item.Name)!=1)
    {
        list.Remove(item);
    }
}
于 2013-02-20T10:53:32.443 回答