如何通过Linq将List中的uniqe元素添加到ObservableCollection

时间:2018-08-09 13:49:55

标签: c# performance linq

我有一个问题,关于检查是否一个列表中的对象是否存在于另一个列表中,如果不是,则由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查询可以更快地做到这一点吗?

3 个答案:

答案 0 :(得分:0)

我认为没有更快的方法,您必须检查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

答案 1 :(得分:0)

  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 });
}

答案 2 :(得分:0)

以下代码应该相当快,因为​​它使用哈希而不是嵌套循环:

// 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 });
    }
}