【问题标题】:Remove duplicates from custom List object [duplicate]从自定义列表对象中删除重复项 [重复项]
【发布时间】:2019-10-03 21:45:08
【问题描述】:

总结:从自定义列表列表中删除重复项

我尝试使用各种现有方法从其他堆栈溢出帖子中删除重复项,一些示例是:

var distinctWords = combinedList.Distinct().ToList();

fooArray.GroupBy(x => x.Id).Select(x => x.First());

这些解决方案仅根据 1 个条件进行过滤,我需要根据 2 个条件删除重复项,如果年份和 id 匹配,则需要删除重复项。可以有不同的年份具有相同的 id。我想在不使用 MoreLINQ 的情况下执行此操作。

型号:

    public class data
    {
        public List<Inventory> inventory { get; set; }
        public List<LocationInventory> locationinventory { get; set; }

    }

    public class Inventory
    {
        public string name{ get; set; }
        public string year{ get; set; }
        public string id{ get; set; }
    }

    public class LocationInventory
    {
        public string location { get; set; }
        public List<Inventory> inventory { get; set; }
    }

控制器:

        public ActionResult getData(string[] Make, string[] Location)
        {
            data inv = new Models.data();

            //Make a list of the inventory lists
            inv.locationinventory = new List<LocationInventory>();

            //Split the Manufacturer and Location at the commas and store in new array
            string[] Make_Values = Make[0].Split(',');
            string[] Location_Values = Location[0].Split(',');

            //Get values for the tables
            var popData = new List<Inventory>();

            foreach (var Location_Value in Location_Values)
            {
                //Populate the data for each location
                //populateData returns a List<Inventory>
                popData = populateData(Make_Values, Location_Value.ToString());

                //Add the data to model with cooresponding location and inventory
                inv.locationinventory.Add(new LocationInventory{ location = Location_Value, inventory = popData });
            }

            return PartialView("Table", inv);
        }

查看:

@{
    var inventories = Model.locationinventory.Select(x => x.inventory).Distinct().ToList();
    var list1 = new List<Project1.Models.Inventory>();
    var list2 = new List<Project1.Models.Inventory>();

    foreach (var inv in inventories)
    {
        if (list1?.Any() != true)
        {
            list1 = inv;
        }

        if (list1?.Any() != false)
        {
            list2 = inv;
        }

        var combinedList = list1.Union(list2);

        var test = combinedList.GroupBy(x => new { x.id, x.year }).ToList();

        <div>
            <table>                
                @foreach (var l in test)
                {
                    foreach (var m in l)
                    {
                        <thead>
                            <tr>
                                <td>@m.name</td>
                                <td>@m.year</td>
                                <td>@m.id</td>
                            </tr>
                        </thead>
                    }
                }
            </table>
        </div>
    }

}

当前结果:

iphone 2019 x1234
iphone 2019 x1234
iphone 2020 x1234
iphone 2018 x1234
iwatch 2019 a4321
iwatch 2020 a4321
android 2020 n9876
android 2020 n9876
android 2019 n9876

预期结果:

iphone 2019 x1234
iphone 2020 x1234
iphone 2018 x1234
iwatch 2019 a4321
iwatch 2020 a4321
android 2020 n9876
android 2019 n9876

【问题讨论】:

  • 如果我理解正确,您需要实现自定义IEqualityComparer&lt;TSource&gt; 以根据您的标准执行比较。看看official documentation here

标签: c# asp.net asp.net-mvc


【解决方案1】:

你有点接近你需要的东西,但并不完整。分组后,您只需从每个组中投影一行:

var uniqueInventory = combinedList.GroupBy(x => new { x.name,x.id, x.year })
                                  .Select(x => x.First())
                                  .ToList();

现在它将为每个组包含一个项目,并且所有项目都是唯一的条目。

另一种方法是实现IEqualityComparer,可以在Distinct方法中传递。

public class InventoryComparer: IEqualityComparer<Inventory>
{
    public override bool Equals(Inventory a, Inventory b)
    {
        return a.name == b.name
            && a.id == b.id
            && a.year == b.year;
    }

    public override int GetHashCode(Inventory inventory)
    {
        return inventory.id.GetHashCode();
    }
}

现在我们可以像这样使用它:

var uniqueInventory = combinedList.Distinct(new InventoryComparer());

【讨论】:

  • 非常感谢!!!这正是我想要做的,你的解决方案完美!
  • 这很酷,我会继续尝试第二种方法以了解更多信息。
  • @DotNetFullStack 为了完整起见,还请查看重复问题的答案中提到的DistinctBy() 方法。
猜你喜欢
  • 2017-06-23
  • 2015-09-12
  • 2015-08-06
  • 2021-12-11
  • 2017-01-11
  • 1970-01-01
  • 2014-09-30
  • 2015-02-22
相关资源
最近更新 更多