c# - 对象列表中的常见对象

时间:2015-04-12 03:05:13

标签: c# linq

我有以下对象列表

列表
List<List<Person>> setofPersons=new List<Lits<Person>>();

我像这样添加项目。

List<Person> firstPersonList=new List<Person>();
Person p1=new Person(100,"James");
Person p2=new Person(200,"Smith");
firstPersonList.Add(p1);
firstPersonList.Add(p2);

setOfPersons.Add(firstPersonList);

List<Person> secondPersonList=new List<Person>();
Person p3=new Person(100,"James");
Person p4=new Person(200,"Smith");
Person p5=new Person(300,"Thomas");
secondPersonList.Add(p3);
secondPersonList.Add(p4);
secondPersonList.Add(p5);

setOfPersons.Add(secondPersonList);

List<Person> thirdPersonList=new List<Person>();
Person p6=new Person(100,"James");
Person p7=new Person(400,"Amy");
thirdPersonList.Add(p6);
thirdPersonList.Add(p7);

setOfPersons.Add(thirdPersonList);

现在我想找出 setOfPersons 中包含的列表中的常见对象。这应该由人Id完成,例如:100,200,300等;

我尝试了以下内容。

List<Person> commonPersons = setOfPersons
    .Where(i => setOfPersons.Skip(1).All(x => x.Contains(i)))
    .ToList();

但问题是commomPersons中的count总是0;

有人可以帮我解决这个问题吗?

修改 我在

中编写了以下方法
              public int CompareTo(object obj)
              {
                       Person p = (Person)obj;
                       if (p.personId == personId)
                             return 1;
                       else
                             return 0;


               }

然后我将LINQ查询更改为以下

              List<Person> commonPersons = setofPersons[0].Where(
                                  i => setofPersons.Skip(1).All(x => i.CompareTo(x))
                              ).ToList();

现在生成编译时错误,说“无法将bool转换为int”。 我是LINQ的新手。有人可以指出我哪里出错了吗?

4 个答案:

答案 0 :(得分:3)

问题是计算机无法知道2个人类实例是否相同。要告诉.NET运行时如何执行此操作,请使Person类实现IComparable,并在那里指定如何比较Person类的2个实例(在您的情况下,您将检查Ids是否相等)。见here

更正:您需要实施IEquatable,与排序/排序相当。

答案 1 :(得分:1)

IComparable / CompareTo用于ordering/sorting。您应该做的是覆盖EqualsGetHashCode或实施IEqualityComparer

简单的相等实现可能如下所示,例如:

public override bool Equals(object obj)
{
    var person = (Person)obj;
    return Equals(Id, person.Id);
}

public override int GetHashCode()
{
    return Id;
}

然后可以通过以下方式找到您的普通人:

var commonPersons = firstPersonList
    .Intersect(secondPersonList)
    .Intersect(thirdPersonList);

对于多个枚举(例如列表列表)的交集,有更有效的方法可以在Intersection of multiple lists with IEnumerable.Intersect()

的答案中显示

答案 2 :(得分:0)

试着在集合中思考......得到你得到的东西,你需要:

  1. 将集合中的所有数据展平为单个人员集合,然后按person.id
  2. 对其进行分组
  3. 然后按人员ID
  4. 对其进行分组
  5. 最后,将它们仅过滤到与原始集合具有相同计数的组。
  6. 代码如下:

    var query = setOfPersons
                .SelectMany(personList => personList.Select(person => person))
                .GroupBy(person => person.Id)
                .Where(group => group.Count() == setOfPersons.Count);
    

    请在此处查看最终示例:https://dotnetfiddle.net/gCgNBf

答案 3 :(得分:0)

您需要做的是将列表列表展平为一个列表。为此,您可以使用SelectMany。

代码如下所示:

var commonPersons = setOfPersons.SelectMany(x => x.Where(y => y.Id == 100));
相关问题