Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在c中基于子数组过滤数组中的重复项#_C#_Linq_Filter_Iequalitycomparer - Fatal编程技术网

C# 在c中基于子数组过滤数组中的重复项#

C# 在c中基于子数组过滤数组中的重复项#,c#,linq,filter,iequalitycomparer,C#,Linq,Filter,Iequalitycomparer,我有一个带有基本代码的人员列表和一系列位置。我需要删除列表中具有相同位置的不同基本代码的人员,并保留具有不同位置的人员 我尝试使用IEqualityComparer和linq的group by,但没有成功。 你们能告诉我怎么做吗? 这是我的班级结构 public class Person { public string Name { get; set; } public List<Location> Locations { get; set; } } public

我有一个带有基本代码的人员列表和一系列位置。我需要删除列表中具有相同位置的不同基本代码的人员,并保留具有不同位置的人员

我尝试使用IEqualityComparer和linq的group by,但没有成功。 你们能告诉我怎么做吗? 这是我的班级结构

public class Person
{
    public string Name { get; set; }

    public List<Location> Locations { get; set; }
}
public class Location
{
    public string Name { get; set; }
    public string BaseCode { get; set; }
}

我想从我的列表中筛选人员2,并保留人员1和人员3。请注意

您可以使用IEquatable接口,并像这样重写Equal和GetHashCode方法:

有问题的更改后编辑:

public class Location : IEquatable<Location>
{    
       public string Name { get; set; }     
       public string BaseCode { get; set; 

        public bool Equals(Location other)
        {
            if (Object.ReferenceEquals(other, null)) return false;

            if (Object.ReferenceEquals(this, other)) return true;
            return BaseCode.Equals(other.BaseCode);
        }

        public override int GetHashCode()
        {
            return BaseCode.GetHashCode();
        }


} 
您可以从

中了解此接口,Adam的解决方案是更“正确”的处理方式。但是如果您想使用LINQ,那么像这样的东西也应该这样做(注意,代码期望位置是有序的,并将字符串作为标识符):

免责声明:此解决方案不专门处理具有不同/相同位置的相同
BaseCode
;你的要求中没有提到这一点。
IEqualityComparer
Route

这里的重要部分是
个人
位置
IEqualityComparer
实现:

class Program
{
    static void Main(string[] args)
    {
        var p1 = new Person {Name ="John", BaseCode="AA12", Locations = new List<Location>
        {
            new Location { Name = "India" },
            new Location { Name = "USA" }
        }};

        var p2 = new Person {Name ="John", BaseCode="AA13", Locations = new List<Location>
        {
            new Location { Name = "India" },
            new Location { Name = "USA" }
        }};

        var p3 = new Person {Name ="John", BaseCode="AA14", Locations = new List<Location>
        {
            new Location { Name = "India" },
            new Location { Name = "UK" }
        }};

        var persons = new List<Person> { p1, p2, p3 };

        // Will not return p2.
        var distinctPersons = persons.Distinct(new PersonComparer()).ToList();

        Console.ReadLine();
    }
}

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

        bool samePerson = x.Name == y.Name;

        bool sameLocations = !x.Locations
            .Except(y.Locations, new LocationComparer())
            .Any();

        return samePerson && sameLocations;
    }

    public int GetHashCode(Person obj)
    {
        return obj.Name.GetHashCode();
    }
}

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

        return x.Name == y.Name;
    }

    public int GetHashCode(Location obj)
    {
        return obj.Name.GetHashCode();
    }
}
这将导致一个更简单的调用:

var distinctPersons = persons.Distinct().ToList();

我很想写下面这样的东西。我还没有检查
y.Locations.Equals()
是否有效,但是用同样的功能替换它应该很简单

    List<Person> personList = new List<Person>();
    List<Person> deduplicatedPersonList = new List<Person>();
    personList.ForEach(x =>
    {
        Person existingPerson = personList.Find(y =>
        {
            if (y.Locations.Equals(x.Locations))
                return false;
            return true;
        });
        if (existingPerson == null)
            deduplicatedPersonList.Add(x);
    });
List personList=new List();
List deduplicatedPersonList=新建列表();
personList.ForEach(x=>
{
Person existingPerson=personList.Find(y=>
{
如果(y位置等于(x位置))
返回false;
返回true;
});
if(existingPerson==null)
重复数据消除PersonList.Add(x);
});

谢谢你的回复,我编辑了我的问题,我在结构中犯了一个大错误,你能再检查一次吗?谢谢你的回复,我编辑了我的问题,我在结构中犯了一个大错误,你能再检查一次吗?你需要更改的一件事是,
BaseCode
似乎是
Location
的成员,不是
。这个问题似乎意味着在比较
位置时应该忽略基本代码,因此
位置比较器
仍然是正确的。@jmh\u gr当我回答时,
基本代码
是对的。但是我的实现对
BaseCode
没有任何作用,因为需求没有指定如果
BaseCode
相等该怎么办。@user783662除了我的示例对象代码之外,解决方案仍然是
BaseCode
没有直接使用。你没有指定当
BaseCode
相等时如何处理。谢谢你的回复,我编辑了我的问题,我在结构中犯了一个大错误,你能再次检查吗?在这种情况下,locations.equal将不起作用。感谢您的回复,我正在尝试此操作,请您解释一下,并且缺少一个结束括号
class Program
{
    static void Main(string[] args)
    {
        var p1 = new Person {Name ="John", BaseCode="AA12", Locations = new List<Location>
        {
            new Location { Name = "India" },
            new Location { Name = "USA" }
        }};

        var p2 = new Person {Name ="John", BaseCode="AA13", Locations = new List<Location>
        {
            new Location { Name = "India" },
            new Location { Name = "USA" }
        }};

        var p3 = new Person {Name ="John", BaseCode="AA14", Locations = new List<Location>
        {
            new Location { Name = "India" },
            new Location { Name = "UK" }
        }};

        var persons = new List<Person> { p1, p2, p3 };

        // Will not return p2.
        var distinctPersons = persons.Distinct(new PersonComparer()).ToList();

        Console.ReadLine();
    }
}

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

        bool samePerson = x.Name == y.Name;

        bool sameLocations = !x.Locations
            .Except(y.Locations, new LocationComparer())
            .Any();

        return samePerson && sameLocations;
    }

    public int GetHashCode(Person obj)
    {
        return obj.Name.GetHashCode();
    }
}

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

        return x.Name == y.Name;
    }

    public int GetHashCode(Location obj)
    {
        return obj.Name.GetHashCode();
    }
}
public class Person : IEquatable<Person>
{
    public string Name { get; set; }
    public string BaseCode { get; set; }
    public List<Location> Locations { get; set; }

    public bool Equals(Person other)
    {
        if (other == null)
            return false;

        bool samePerson = Name == other.Name;

        // This is simpler because of IEquatable<Location>
        bool sameLocations = !Locations.Except(other.Locations).Any();

        return samePerson && sameLocations;
    }

    public override int GetHashCode()
    {
        return Name.GetHashCode();
    }
}

public class Location : IEquatable<Location>
{
    public string Name { get; set; }

    public bool Equals(Location other)
    {
        if (other == null)
            return false;

        return Name == other.Name;
    }

    public override int GetHashCode()
    {
        return Name.GetHashCode();
    }
}
var distinctPersons = persons.Distinct().ToList();
    List<Person> personList = new List<Person>();
    List<Person> deduplicatedPersonList = new List<Person>();
    personList.ForEach(x =>
    {
        Person existingPerson = personList.Find(y =>
        {
            if (y.Locations.Equals(x.Locations))
                return false;
            return true;
        });
        if (existingPerson == null)
            deduplicatedPersonList.Add(x);
    });