【问题标题】:How add uniqe element from List to ObservableCollection by Linq如何通过 Linq 将 List 中的唯一元素添加到 ObservableCollection
【发布时间】:2018-08-09 13:49:54
【问题描述】:

我有一个关于检查一个列表中的对象是否存在于另一个列表中的问题,如果不存在,则全部由 Linq 将它们添加到第二个列表中。其实我有两个循环有一个条件:

 foreach (var p in seznamVlaku.Select(s => s.ProjizdejiciStanicemi)) {
            foreach (var l in p) {
                if(_nodes.Any(a => a.ID != l.Key.ID)){
                    _nodes.Add(new Node() {Name = l.Key.Jmeno, ID = l.Key.ID, X = l.Key.X, Y = l.Key.Y });
                }
            }
        }

可以通过 Linq 查询更快地做到这一点吗?

【问题讨论】:

  • 这个_nodes.Any(a => a.ID != l.Key.ID) 的意思是'如果存在具有不同id 的节点则_nodes.Add(...)'。是错字吗?不应该是:!_nodes.Any(a => a.ID == l.Key.ID) 吗?
  • 您可以使用IEnumerable.Except() 过滤掉存在于不同列表中的元素。 NewList.AddRange(OriginalList.Except(TheOtherList));
  • @BradleyUffner 需要自定义相等比较器,或 MoreLinq 的 ExceptBy
  • 法比安你说得对:)
  • _nodesList<T> 集合吗?

标签: c# performance linq


【解决方案1】:

我认为没有更更快的方法,您必须检查l 是否已存在于_nodes 中,以及每个l 中是否存在。如果您可以在更高级别上对其进行优化,我不知道这是在做什么。

如果你只是想要一个更短的 LINQ 语句,你可以使用SelectMany:

foreach(var l in sznamVlaku.SelectMany(s => s.ProjizdejiciStanicemi)
                           .Where(x => _nodes.All(a => a.ID != x.Key.ID)))
    _nodes.Add(new Node() {Name = l.Key.Jmeno, ID = l.Key.ID, X = l.Key.X, Y = l.Key.Y });

请注意,我使用了All 而不是Any,因为您想查找所有l,其中所有 节点具有不同的ID

【讨论】:

    【解决方案2】:
    1. 您不需要两个 foreach。而是使用 SelectMany。

    你的例子:

    foreach (var p in seznamVlaku.Select(s => s.ProjizdejiciStanicemi))
    {
        foreach (var l in p)
        {
        }
    }
    

    我们可以这样写,结果是一样的:

    foreach (var node in seznamVlaku.SelectMany(list => list.ProjizdejiciStanicemi))
    {
    }
    
    1. 您可以将条件(现有项)添加到 linq 查询的管道中

    代码:

    foreach (var node in seznamVlaku
        .SelectMany(list => list.ProjizdejiciStanicemi)
        .Where(item => nodes
            .Exists(node => node.ID != item.ID)))
    {
        _nodes.Add(new Node() {Name = node.Key.Jmeno, ID = node.Key.ID, X = node.Key.X, Y = node.Key.Y });
    }
    

    【讨论】:

      【解决方案3】:

      以下代码应该更快,因为它使用散列而不是嵌套循环:

      // build a HashSet of your key's type (I'm assuming integers here) containing all your current elements' keys in the _nodes ObservableCollection
      HashSet<int> hashSet = new HashSet<int>(_nodes.Select(n => n.ID));
      
      foreach (var l in seznamVlaku.SelectMany(s => s.ProjizdejiciStanicemi)) {
          // if you can add the element's ID to the HashSet it hasn't been added before
          if(hashSet.Add(l.Key.ID)) {
              _nodes.Add(new Node() {Name = l.Key.Jmeno, ID = l.Key.ID, X = l.Key.X, Y = l.Key.Y });
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-29
        • 2016-04-26
        相关资源
        最近更新 更多