在列表中添加之前,如何检查item的值不等于零?

时间:2014-02-11 13:49:19

标签: c# linq

我有两个列表double list1和list2。我正在比较两个列表,并对list2中list1匹配项目的项目索引感兴趣。我在linq表达式下面使用:

List<double>  list1 = new List<double> () {1.0 , 2.0 , 5.0 , 7.0 , 8.0} ;
List<double> list2 = new List<double> () {2.0 ,7.0 ,9.0} ;
List<int> kk= new List <int> () ;
list2.ForEach (xx => kk.Add (list1.Select((v, i) => new { v, i }).Where(x => x.v == xx).Select(x => x.i).FirstOrDefault ()));

如果list1中的项目不存在于list1中,那么我在上面的语句中有一个问题,那么我得到0值作为回报,这个零值在列表kk中添加。如何在列表kk中添加0值来避免。

2 个答案:

答案 0 :(得分:2)

您遇到问题,因为如果未找到匹配项,则选择默认值(零)。我建议你使用join - 它也比迭代外部序列中每个项目的内部序列更快(O(N)而不是搜索:

from x in list1.Select((l1,i) => new { l1, i })
join l2 in list2 on x.l1 equals l2
select x.i

或lambda语法:

list1.Select((l1,i) => new { l1, i })
     .Join(list2, x => x.l1, l2 => l2, (x, l2) => x.i);

内部连接创建内部序列的查找(在这种情况下为list2) - 在内部序列上进行单次迭代。然后我们需要在外部序列上进行一次迭代,以从查找中获取连接的内部项。类似的东西:

public IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
    this IEnumerable<TOuter> outer,
    IEnumerable<TInner> inner,
    Func<TOuter, TKey> outerKeySelector,
    Func<TInner, TKey> innerKeySelector,
    Func<TOuter, TInner TResult> resultSelector)
{
     var lookup = inner.ToLookup(innerKeySelector); // iterate over list2

     foreach(var outerItem in outer)
     {
          var joined = lookup[outerKeySelector(outerItem)]; // quick search, O(1)
          if (!joined.Any())
              continue; // go to next outer item if no matches exist

          foreach(var joindeItem in joined) // iterate over matches
              yield return resultSelector(outerItem, joinedItem); // return index
     }
}

实际实施稍微优化一点,但核心理念是一样的。

答案 1 :(得分:0)

您的大多数代码都忙于查找列表中给定元素的索引。 List<T>已经有一个方法IndexOf,如果找到该项,则返回索引;如果不找到,则返回-1

如果您不关心性能(运行时为list1.Count * list2.Count),您可以使用:

kk = list2.Select(xx => list1.IndexOf(xx)).Where(i => (i >= 0)).ToList();

如果效果很重要,则需要将list1转换为Dictionary<double, int>,将运行时间缩短为list1.Count + list2.Count