Linq同时收集了2个

时间:2016-07-20 14:09:07

标签: c# linq

我有两个清单:

List<A> listA1 = GetFirstList();
List<A> listA2 = GetSecondList();

class A定义

class A
{
    public int Id {get; set;}
    public DateTime ModifiedDate {get; set;}
    public string Type {get; set;}
}

我正在根据以下某些条件做一些事情。

List<A> listA1 = GetFirstList();
List<A> listA2 = GetSecondList();
List<A> result = new List<A>();
for(int i = 0; i < listA1; i++)
{
    if(listA1[i].ModifiedDate != listA2[i].ModifiedDate)
    {
        result.Add(listA1[i]);
    }
}

假设:两个列表都包含相同数量的项目,其中IdType的顺序相同。这就是为什么我只是检查ModifiedDate并因为项目数量和订单而自动处理休息。

我使用LINQ更改了它,如下所示,它工作正常。

var match = ListA1
      .Where(a => listA2.First(ct => ct.Id == a.Id).ModifiedDate != a.ModifiedDate);
result.AddRange(match);

但它将遍历ListA1ListA2,但在第一种情况下,它只迭代一次。

我的问题是,我可以通过保留其他收藏的索引来LINQ吗?换句话说,我可以使LINQ比现在更优化吗?

3 个答案:

答案 0 :(得分:7)

您可以使用Enumerable.Zip按索引链接两个序列:

List<A> result = listA1.Zip(listA2, (a1, a2) => new { a1, a2 })
    .Where(x => x.a1.ModifiedDate != x.a2.ModifiedDate)
    .Select(x => x.a1)
    .ToList();

即使两个序列都没有实现IList / IList<T>,这也会有效,因此无法通过索引访问这些项目。

答案 1 :(得分:3)

你可以使用这个衬垫:

List<A> result = listA1.Where((t, i) => t.ModifiedDate != listA2[i].ModifiedDate).ToList();

答案 2 :(得分:0)

您可以使用listA1.Except(listA2,cmp),其中cmp是IComparer。类似的东西:

void Main()
{
    List<A> listA1 = new List<A> {
       new A { Id=1, ModifiedDate=new DateTime(2016,1,1), Type="A"},
       new A { Id=2, ModifiedDate=new DateTime(2016,1,2), Type="A"},
       new A { Id=3, ModifiedDate=new DateTime(2016,1,3), Type="A"},
       new A { Id=4, ModifiedDate=new DateTime(2016,1,4), Type="A"},
    };
    List<A> listA2 = new List<A> {
       new A { Id=1, ModifiedDate=new DateTime(2016,1,1), Type="A"},
       new A { Id=2, ModifiedDate=new DateTime(2016,1,2), Type="A"},
       new A { Id=3, ModifiedDate=new DateTime(2016,1,3), Type="A"},
       new A { Id=4, ModifiedDate=new DateTime(2016,1,5), Type="A"},
       new A { Id=5, ModifiedDate=new DateTime(2016,1,6), Type="A"},
       new A { Id=6, ModifiedDate=new DateTime(2016,1,7), Type="A"},
    };

    var cmp = new AEqualityComparer();
    var result = listA1.Except(listA2, cmp);

    foreach (var item in result)
    {
        Console.WriteLine("Id:{0}, Date:{1}",item.Id, item.ModifiedDate);
    }
}

public class A
{
    public int Id { get; set; }
    public DateTime ModifiedDate { get; set; }
    public string Type { get; set; }
}

public class AEqualityComparer : IEqualityComparer<A>
{
    public bool Equals(A x, A y)
    {
        return x.Id == y.Id && x.ModifiedDate == y.ModifiedDate;
    }

    public int GetHashCode(A obj)
    {
        return obj.ToString().GetHashCode();
    }
}