首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何有效地比较列表?

如何有效地比较列表?
EN

Stack Overflow用户
提问于 2017-02-23 10:46:27
回答 4查看 984关注 0票数 6

我目前正在用asp.net开发一个web应用程序。在某些api调用中,有必要将ListA与列表的ListB进行比较,以确定ListA是否具有ListB中任何列表的相同元素。换句话说:如果ListA包含在ListB中。

两个集合都使用EF-Code-First db的Linq查询。ListB要么有一个匹配列表,要么没有,从来没有超过一个。在最坏的情况下,ListB有数以百万计的元素,因此比较需要具有可伸缩性。

我没有执行嵌套的foreach循环,而是寻找一个纯linq查询,它将让db完成工作。(在考虑多列索引之前)

为了说明这一结构:

代码语言:javascript
复制
//In reality Lists are queried of EF 
var ListA = new List<Element>();
var ListB = new List<List<Element>>(); 
List<Element> solution;
bool flag = false;
foreach (List e1 in ListB) {
   foreach(Element e2 in ListA) {
        if (e1.Any(e => e.id == e2.id)) flag = true;
        else {
             flag = false;
             break;
        }
    }
        if(flag) {
           solution = e1;
           break;
        }
}

更新结构

因为它是EF数据库,所以我将提供相关的对象结构。我不确定是否允许我发布真实的代码,所以这个例子仍然是通用的。

代码语言:javascript
复制
//List B
class Result {
       ...
       public int Id;

       public virtual ICollection<Curve> curves; 

       ...
}

class Curve {
       ...
       public int Id;

       public virtual Result result;
       public int resultId;

       public virtual ICollection<Point> points;
       ...
}
public class Point{
    ...
    public int Id;
    ...
}

控制器(用于api-调用)想要服务于正确的曲线对象。为了识别正确的对象,提供了一个过滤器(ListA) (实际上是一个曲线对象),现在需要将过滤器(ListA)与结果曲线列表(ListB)进行比较。(因此,事实上比较列表)曲线有1-50分左右。结果可能有500.000.000曲线

这里可以通过对象标识进行比较,因为所有对象(甚至过滤器)都是重新查询数据库的。

我正在寻找一种实现这种机制的方法,而不是如何绕过这种情况。(例如使用多列索引(更改表))

(为说明目的):

代码语言:javascript
复制
class controller {
    ...
    public Response serveRequest(Curve filter) {
         foreach(Curve c in db.Result.curves) {
               if(compare(filter.points , c.points)) return c;

         }
    }
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-02-23 11:44:59

使用但下列情况除外:

代码语言:javascript
复制
    public static bool ContainsAllItems(IList<T> listA, IList<T> listB)
    {
        return !listB.Except(listA).Any();
    }

上述方法将告诉listA是否包含listB或not..and的所有元素,其复杂度要比O(n*m)方法快得多。

票数 1
EN

Stack Overflow用户

发布于 2017-02-23 11:30:36

试试这个:

代码语言:javascript
复制
bool isIn = ListB.Any(x=>x.Count==ListA.Count && ListA.All(y=>x.Contains(y)));

或者,如果你想要元素

代码语言:javascript
复制
var solution = ListB.FirstOrDefault(x=>x.Count==ListA.Count && ListA.All(y=>x.Contains(y)));
票数 0
EN

Stack Overflow用户

发布于 2017-02-23 11:46:38

我有些东西要给你:

代码语言:javascript
复制
var db = new MyContext();

var a = db.LoadList(); // or whatever
var b = new List<IQueryable<Entities>>(db.LoadListOfLists()/*or whatever*/);

b.Any(x => x.Count.Equals(a.Count) & x.All(y => a.Any(z => z.Id == y.Id)));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42413513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档