如何使两个以上的值集/列表相交?

发布于 2024-12-03 08:34:35 字数 1233 浏览 0 评论 0原文

下面是一个在 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();

谢谢!

Here is an example that works in Linqpad. The problem is that I need it to work for more than two words, e.g. searchString = "headboard bed railing". This is a query against an index and instead of "Match Any Word" which I've done, I need it to "Match All Words", where it finds common key values for each of the searched words.

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

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

林空鹿饮溪 2024-12-10 08:34:35

交集的交集是可交换的和结合的。这意味着 (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();

Intersection of an intersection is commutative and associative. This means that (A ∩ B ∩ C) = (A ∩ (B ∩ C)) = ((A ∩ B) ∩ C), and rearranging the order of the lists will not change the result. So just apply .Intersect() multiple times:

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

So, to make your code more general:

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();
莫相离 2024-12-10 08:34:35

要以 @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();

To build on @cdhowie's answer, why use Intersect? I would think you could make it more efficient by building your query in multiple steps. Something like...

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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文