Как я могу пересечь более двух наборов / списков значений? - PullRequest
2 голосов
/ 06 сентября 2011

Вот пример, который работает в Linqpad.Проблема в том, что мне нужно, чтобы он работал более чем на два слова, например searchString = "перила кровати изголовья".Это запрос к индексу, и вместо «Сопоставить любое слово», которое я сделал, мне нужно «Сопоставить все слова», чтобы найти общие значения ключа для каждого из искомых слов.

Спасибо! * * 1004

Ответы [ 2 ]

3 голосов
/ 06 сентября 2011

Пересечение пересечения является коммутативным и ассоциативным. Это означает, что (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();
0 голосов
/ 06 сентября 2011

Чтобы использовать ответ @ 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();
...