如何交叉两组以上的值/值列表?

时间:2011-09-06 17:01:20

标签: linq list linq-to-entities intersect

这是一个适用于Linqpad的示例。问题是我需要它才能使用两个以上的单词,例如searchString =“床头板栏杆”。这是对索引的查询,而不是我已经完成的“匹配任何单词”,我需要它来“匹配所有单词”,在那里找到每个搜索单词的公共键值。

//Match ALL words for categories in index
string searchString = "headboard bed";

List<string> searchList = new List<string>(searchString.Split(' '));

string word1 = searchList[0];
string word2 = searchList[1];

var List1 = (from i in index
            where i.word.ToUpper().Contains(word1)
            select i.category.ID).ToList();         

var List2 = (from i in index
            where i.word.ToUpper().Contains(word2)
            select i.category.ID).ToList();             

//How can I make this work for more than two Lists?
var commonCats = List1.Intersect(List2).ToList();

var category = (from i in index
           from s in commonCats
           where commonCats.Contains(i.category.ID)
           select new 
           {
               MajorCategory = i.category.category1.description,
               MinorCategory = i.category.description,
               Taxable = i.category.taxable,
               Life = i.category.life,
               ID = i.category.ID
           }).Distinct().OrderBy(i => i.MinorCategory);

category.Dump();

谢谢!

2 个答案:

答案 0 :(得分:3)

交叉点的交叉点是可交换的和关联的。这意味着(A∩B∩C)=(A∩(B∩C))=((A∩B)∩C),重新排列列表的顺序不会改变结果。所以只需多次应用.Intersect()

var commonCats = List1.Intersect(List2).Intersect(List3).ToList();

所以,为了使你的代码更通用:

var searchList = searchString.Split(' ');

// Change "int" if this is not the type of i.category.ID in the query below.
IEnumerable<int> result = null;

foreach (string word in searchList)
{
    var query = from i in index
                where i.word.ToUpper().Contains(word1)
                select i.category.ID;

    result = (result == null) ? query : result.Intersect(query);
}

if (result == null)
    throw new InvalidOperationException("No words supplied.");

var commonCats = result.ToList();

答案 1 :(得分:0)

要建立@ cdhowie的答案,为什么要使用Intersect?我认为通过多个步骤构建查询可以提高效率。有点像...

if(string.IsNullOrWhitespace(search))
{
    throw new InvalidOperationException("No word supplied.");
}

var query = index.AsQueryable();

var searchList = searchString.Split(' ');

foreach (string word in searchList)
{
    query = query.Where(i => i.word.ToUpper().Contains(word));
}

var commonCats = query.Select(i => i.category.ID).ToList();