我有一个项目对象列表:
IEnumerable<Project> projects
项目类作为名为标记的属性。这是 int []
我有一个名为 filteredTags 的变量,它也是 int [] 。
所以我想说我的过滤标签变量如下所示:
int[] filteredTags = new int[]{1, 3};
我想过滤我的列表(项目),只返回包含过滤器中列出的所有标记的项目(在这种情况下,至少标记1和标记中的标记3 属性)。
我尝试使用 Where ()和包含(),但只有在我与单个值进行比较时才会起作用。我如何将列表与另一个列表进行比较,我需要对过滤列表中的所有项目进行匹配?
答案 0 :(得分:39)
编辑:更好的是,这样做:
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
,否则计数比较将无法按预期工作。
答案 1 :(得分:3)
我们应该让项目包括(至少)所有过滤的标签,或以不同的方式说明,排除不包括所有过滤标签的项目。
因此,我们可以使用Linq Except
来获取未包含的标记。然后我们可以使用Count() == 0
只包含那些不包含标签的内容:
var res = projects.Where(p => filteredTags.Except(p.Tags).Count() == 0);
或者我们可以通过将Count() == 0
替换为!Any()
:
var res = projects.Where(p => !filteredTags.Except(p.Tags).Any());
答案 2 :(得分:2)
var result = projects.Where(p => filtedTags.All(t => p.Tags.Contains(t)));
答案 3 :(得分:1)
var filtered = projects;
foreach (var tag in filteredTags) {
filtered = filtered.Where(p => p.Tags.Contains(tag))
}
这种方法的好处在于您可以逐步优化搜索结果。
答案 4 :(得分:0)
基于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);
}
答案 5 :(得分:-1)
试试这个:
var filteredProjects =
projects.Where(p => filteredTags.All(tag => p.Tags.Contains(tag)));