从List< Object>中删除重复项.使用LINQ [英] Remove duplicates from a List<Object> using LINQ

查看:93
本文介绍了从List< Object>中删除重复项.使用LINQ的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题很简单,在SO中进行简单的搜索就可以找到许多类似的问题,但是我仍在努力寻找答案.

The question is straightforward and a simple search in SO gives a number of similar questions but I'm still struggling to get an answer for this.

我想根据它们具有的所有属性从List<Column> columns中删除重复的对象. Column类本身具有List<string>属性,这是我认为可能在GetHashCode()Equals部分出现问题的地方.

I want to remove the duplicate objects from List<Column> columns based on all the properties they have. The Column class itself has a List<string> property and this is where I think I have problems maybe in the GetHashCode() or Equals part.

这是我编写的完整代码,但没有得到正确的结果.例如,在下面的代码中,我想删除column3,因为它在各个方面都与column1相同.

Here is the full code I've written but I'm not getting the correct results. For example in the code below, I want to remove column3 because it is the same as column1 in every aspect.

using System;
using System.Collections.Generic;
using System.Linq;

namespace Arrays
{
    public class ColumnList
    {
        public static void RemoveDuplicateColumnTypes()
        {
            // define columns
            var column1 = new Column
            {
                StartElevation = 0,
                EndElevation = 310,
                ListOfSections = new List<string> { "C50", "C40" }
            };
            var column2 = new Column
            {
                StartElevation = 0,
                EndElevation = 310,
                ListOfSections = new List<string> { "C50", "C30" }
            };
            var column3 = new Column
            {
                StartElevation = 0,
                EndElevation = 310,
                ListOfSections = new List<string> { "C50", "C40"}
            };

            // list of columns
            var columns = new List<Column> { column1, column2, column3 };

            var result = columns.Distinct(new ColumnListComparer());
        }
    }

    public class ColumnListComparer : IEqualityComparer<Column>
    {
        public bool Equals(Column x, Column y)
        {
            if (x == null || y == null) return false;

            if (Math.Abs(x.StartElevation - y.StartElevation) < 0.001 &&
                Math.Abs(x.EndElevation - y.EndElevation) < 0.001 &&
                x.ListOfSections.SequenceEqual(y.ListOfSections))
            {
                return true;
            }
            return false;
        }

        public int GetHashCode(Column obj)
        {
            return obj.StartElevation.GetHashCode() ^
                   obj.EndElevation.GetHashCode() ^
                   obj.ListOfSections.GetHashCode();
        }
    }

    public class Column
    {
        public double StartElevation { get; set; }
        public double EndElevation { get; set; }
        public List<string> ListOfSections { get; set; }
    }

}

推荐答案

列表的哈希码不匹配.因此,整个哈希码将不匹配.

The hash code for the lists is not going to match. So the whole hash code won't match.

尝试一下:

 public int GetHashCode(Column obj)
 {
     return 42;
 }

如果对象相等,则哈希码必须相等.通常,返回固定数字并不理想,但从字面上看是有效的.为什么是42?搭便车的爱好者.

Hash codes must be equal if the objects are equal. It is not ideal in general to return a fixed number, but it is entitily valid. Why 42? Hitch hikers fan.

如果这行得通,那么您可以寻找一个更好的哈希函数,该函数实际上使用列表中的某些值.

If that works, then you can look for a better hash function that actually uses some of the values in the list.

只要遵循对象的黄金法则,则使哈希函数的复杂程度取决于您,它们的哈希函数必须相等.

How complex you make the hash function is up to you as long as you follow the golden rule of objects are equal, their hash functions must be equal.

例如,这里是一个仅考虑列表长度的有效哈希函数:

Here is for example a valid hash function that just takes into account the length of the list:

 public int GetHashCode(Column obj)
 {
    return obj.ListOfSections.Count;
 }

这篇关于从List&lt; Object&gt;中删除重复项.使用LINQ的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆