Подтвердить что ты не робот

Фильтрация списка с помощью LINQ

У меня есть список объектов проекта:

IEnumerable<Project> projects

a Проект как свойство, называемое Теги. это int []

У меня есть переменная, называемая отфильтрованной теги, которая также является int [].

Итак, скажем, переменная фильтрованных тегов выглядит так:

 int[] filteredTags = new int[]{1, 3};

Я хочу отфильтровать свой список (projects), чтобы возвращать только проекты, в которых есть ВСЕ теги, перечисленные в фильтре (в этом случае, по крайней мере, тег 1 И тег 3 в тегах ).

Я пытался использовать Где() и Содержит(), но это работает, только если я сравниваю одно значение. Как бы это сделать, чтобы сравнить список с другим списком, где мне нужно совпадение по всем элементам в отфильтрованном списке?

4b9b3361

Ответ 1

EDIT: еще лучше, сделайте так:

var filteredProjects = 
    projects.Where(p => filteredTags.All(tag => p.Tags.Contains(tag)));

EDIT2: Честно говоря, я не знаю, какой из них лучше, поэтому, если производительность не является критичной, выберите ту, которую вы считаете более читаемой. Если это так, вам придется каким-то образом оценить его.


Вероятно, Intersect - это путь:

void Main()
{
    var projects = new List<Project>();
    projects.Add(new Project { Name = "Project1", Tags = new int[] { 2, 5, 3, 1 } });
    projects.Add(new Project { Name = "Project2", Tags = new int[] { 1, 4, 7 } });
    projects.Add(new Project { Name = "Project3", Tags = new int[] { 1, 7, 12, 3 } });

    var filteredTags = new int []{ 1, 3 };
    var filteredProjects = projects.Where(p => p.Tags.Intersect(filteredTags).Count() == filteredTags.Length);  
}


class Project {
    public string Name;
    public int[] Tags;
}

Хотя сначала это кажется немного уродливым. Вы можете сначала применить Distinct к filteredTags, если вы не уверены, все ли они уникальны в списке, иначе сравнение отсчетов не будет работать должным образом.

Ответ 2

var result = projects.Where(p => filtedTags.All(t => p.Tags.Contains(t)));

Ответ 3

var res = projects.Where(p => filteredTags.Except(p.Tags).Count() == 0);

Ответ 4

var filtered = projects;
foreach (var tag in filteredTags) {
  filtered = filtered.Where(p => p.Tags.Contains(tag))
}

Хорошая вещь с этим подходом заключается в том, что вы можете улучшить результаты поиска постепенно.

Ответ 5

На основе http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b,

EqualAll - это подход, который наилучшим образом отвечает вашим потребностям.

public void Linq96() 
{ 
    var wordsA = new string[] { "cherry", "apple", "blueberry" }; 
    var wordsB = new string[] { "cherry", "apple", "blueberry" }; 

    bool match = wordsA.SequenceEqual(wordsB); 

    Console.WriteLine("The sequences match: {0}", match); 
} 

Ответ 6

Попробуйте следующее:

var filteredProjects = 
projects.Where(p => filteredTags.All(tag => p.Tags.Contains(tag)));