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

Posted

技术标签:

【中文标题】在添加列表之前如何检查项目的值不等于零?【英文标题】:How to check value of item is not equal to zero before adding in a list? 【发布时间】:2014-03-09 08:21:23 【问题描述】:

我有两个双 list1 和 list2 列表。我正在比较两个列表,并对 list1 中的项目索引感兴趣,与 list2 中的项目匹配。我正在使用以下 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 ()));

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

【问题讨论】:

你可以使用AddRangeTake(1)代替AddFirstOrDefault 【参考方案1】:

您有问题,因为如果未找到匹配项,则选择默认值(零)。我建议您使用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);

Internally Join 为内部序列(在本例中为 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
     

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

【讨论】:

你能解释一下,join 方法在这种情况下是如何工作的。我想使用自定义相等方法来比较相等的值。 @User1551892 当然,我正在将这个添加到我的答案中:)【参考方案2】:

您的大部分代码都忙于查找列表中给定元素的索引。 List&lt;T&gt; 已经有一个方法 IndexOf 如果找到该项目则返回索引,如果没有则返回 -1

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

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

如果性能很重要,您需要将list1 转换为Dictionary&lt;double, int&gt;,将运行时间减少到list1.Count + list2.Count

【讨论】:

我正在处理双打,我必须考虑精度,我正在使用自定义相等方法来比较双打。因此我没有使用 Indexof 方法。

以上是关于在添加列表之前如何检查项目的值不等于零?的主要内容,如果未能解决你的问题,请参考以下文章

PHP如果变量等于下拉列表中的值,则将“选定”属性添加到选项

字典使所有键的值等于最近的键/值添加

if判断Integer类型的值不等于‘‘导致的查询条件限制缺失

pandas筛选dataframe数据:指定一个数据列的值不等于某个固定值,而且另外一个数据列的值大于某一阈值

在excel中如果元素等于零就删除该行的方法?

如何在添加记录之前检查表中的现有列?