Вопрос по c#, linq – linq где список содержит любой в списке

96

Используя linq, как я могу получить список элементов, где его список атрибутов соответствует другому списку?

Возьмите этот простой пример и псевдокод:

List<Genres> listofGenres = new List<Genre>() { "action", "comedy" });   
var movies = _db.Movies.Where(p => p.Genres.Any() in listofGenres);

Ваш Ответ

5   ответов
174

var movies = _db.Movies.Where(p => p.Genres.Intersect(listOfGenres).Any());
@JonSkeet Я всегда использую метод Contains для подобных запросов. Мне было любопытно увидеть ваш ответ, проверил внутреннюю реализацию и обнаружил, что Intersect использует Set. Можете ли вы сказать мне разницу в производительности между этими двумя методами?
@stom: у нас нет достаточно информации, чтобы помочь вам с этим - вам следует задать новый вопрос сlot больше контекста.
@ Пользователь Пожалуйста, не используйте комментарии к ответам, чтобы попытаться привлечь внимание к другим вопросам.
@Rebornx: ИспользованиеContains многократно заканчивается как O (x * y) операция во времени, но O (1) в пространстве, где x - размер первой коллекции, а y - размер второй. С помощьюIntersect имеет значение O (x + y) во времени, но O (y) в пространстве - он создает хэш-набор из второй коллекции, что позволяет быстро проверять наличие любого элемента из первой коллекции. Увидетьcodeblog.jonskeet.uk/2010/12/30/… для деталей
Я пытался использовать этот запрос для окна поиска, он ищет любой символ в столбце Person_Name, я получил эту ошибку: & Dpos; DbIntersectExpression требует аргументов с совместимой коллекцией ResultTypes & apos; так что я попробовал.StartWith, .EndsWith, .Contains отhere это работает, но что можно сделать, чтобы использовать ваш запрос
2

HashSet вместоList заlistofGenres ты можешь сделать:

var genres = new HashSet<Genre>() { "action", "comedy" };   
var movies = _db.Movies.Where(p => genres.Overlaps(p.Genres));
0

var movies = _db.Movies.TakeWhile(p => p.Genres.Any(x => listOfGenres.Contains(x));

Is & quot; TakeWhile & quot; хуже чем "где" в смысле производительности или ясности?

TakeWhile это другая функция - она прекратит итерацию, когда не найдет совпадения.
54

Contains запрос для этого:

var movies = _db.Movies.Where(p => p.Genres.Any(x => listOfGenres.Contains(x));
1

class Movie
{
  public string FilmName { get; set; }
  public string Genre { get; set; }
}

...

var listofGenres = new List<string> { "action", "comedy" };

var Movies = new List<Movie> {new Movie {Genre="action", FilmName="Film1"},
                new Movie {Genre="comedy", FilmName="Film2"},
                new Movie {Genre="comedy", FilmName="Film3"},
                new Movie {Genre="tragedy", FilmName="Film4"}};

var movies = Movies.Join(listofGenres, x => x.Genre, y => y, (x, y) => x).ToList();

Похожие вопросы