C# 在添加列表之前,如何检查项的值不等于零?

C# 在添加列表之前,如何检查项的值不等于零?,c#,linq,C#,Linq,我有两个清单,分别是清单1和清单2。我正在比较这两个列表,并且对列表1中的项目索引和列表2中的匹配项目感兴趣。我使用以下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

我有两个清单,分别是清单1和清单2。我正在比较这两个列表,并且对列表1中的项目索引和列表2中的匹配项目感兴趣。我使用以下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=newlist(){1.0,2.0,5.0,7.0,8.0};
list2=新列表(){2.0,7.0,9.0};
List kk=新列表();
list2.ForEach(xx=>kk.Add(list1.Select((v,i)=>new{v,i})。其中(x=>x.v==xx)。Select(x=>x.i)。FirstOrDefault());

我对上面的语句有一个问题,若列表2中的项在列表1中不存在,那个么我得到的返回值为0,这个零值添加到列表kk中。如何避免在列表kk中添加0值。

您遇到了问题,因为如果找不到匹配项,您将选择默认值(零)。我建议您使用-它也比在外部序列(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
     }
}
public IEnumerable连接(
这是数不清的外部,
我可数的内心世界,
Func outerKeySelector,
Func innerKeySelector,
Func结果选择器)
{
var lookup=internal.ToLookup(innerKeySelector);//遍历列表2
foreach(外部的变量outerItem)
{
var joined=lookup[outerKeySelector(outerItem)];//快速搜索,O(1)
如果(!joined.Any())
continue;//如果不存在匹配项,则转到下一个外部项
foreach(var joindeItem in join)//迭代匹配
产生返回结果选择器(outerItem,joinedItem);//返回索引
}
}

实际实现稍微优化了一点,但核心思想是相同的。

大多数代码都忙于在列表中查找给定元素的索引。
list
已经有了一个方法
IndexOf
,如果找到了项,则返回索引;如果没有找到项,则返回
-1

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

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

如果性能很重要,您需要使用
字典转换
list1
,将运行时减少到
list1.Count+list2.Count

您可以使用
AddRange
Take(1)
我在处理double,而不是
Add
FirstOrDefault
我要考虑精度,我使用自定义相等方法来比较double。因此,我没有使用Indexof方法。你能解释一下,join方法在这种情况下是如何工作的吗?我想使用自定义相等方法来比较相等值USS1551892当然,我正在把这个添加到我的答案中: