Linq 相交以根据列表筛选多个条件

本文关键字:筛选 条件 列表 Linq | 更新日期: 2023-09-27 18:30:55

我正在尝试按部门过滤用户。筛选器可能包含多个部门,用户可能属于多个部门 (n:m)。 我正在摆弄 LINQ,但找不到解决方案。下面的示例代码使用简化Tuples只是为了使其可运行,当然也有一些真实的用户对象。

同样在CSSharpPad上,所以你有一些可运行的代码:http://csharppad.com/gist/34be3e2dd121ffc161c4

string Filter = "Dep1"; //can also contain multiple filters
var users = new List<Tuple<string, string>>
{
    Tuple.Create("Meyer", "Dep1"),
    Tuple.Create("Jackson", "Dep2"),
    Tuple.Create("Green", "Dep1;Dep2"),
    Tuple.Create("Brown", "Dep1")
};
//this is the line I can't get to work like I want to
var tuplets = users.Where(u => u.Item2.Intersect(Filter).Any());

if (tuplets.Distinct().ToList().Count > 0)
{
    foreach (var item in tuplets) Console.WriteLine(item.ToString());
}
else
{
    Console.WriteLine("No results");
}

现在它返回:

(Meyer, Dep1)
(Jackson, Dep2)
(Green, Dep1;Dep2)
(Brown, Dep1)

我希望它返回的是:迈耶,格林,布朗。如果Filter设置为"Dep1;Dep2"我想做一个OR比较并找到*Meyer,Jackson,Green,Brown"(以及不同的,因为我不想要绿色两次)。如果Filter被设置为"Dep2"我只想拥有杰克逊,格林。我也玩过.Split(';'),但它让我一无所获。

我说得有道理吗?我有具有单个/多个部门的用户,并希望对这些部门进行筛选。在我的输出中,我希望拥有来自指定部门的所有用户。LINQ 魔法对我来说不是那么强烈。

Linq 相交以根据列表筛选多个条件

由于

string实现了IEnumerable,你现在正在做的是对IEnumerable<char>Intersect(即你正在检查字符串中的每个字母)。您需要在Item2Filter上拆分;并相交。

var tuplets = users.Where(u => 
    u.Item2.Split(new []{';'})
    .Intersect(Filter.Split(new []{';'}))
    .Any());
        string[] Filter = {"Dep1","Dep2"}; //Easier if this is an enumerable
        var users = new List<Tuple<string, string>>
        {
            Tuple.Create("Meyer", "Dep1"),
            Tuple.Create("Jackson", "Dep2"),
            Tuple.Create("Green", "Dep1;Dep2"),
            Tuple.Create("Brown", "Dep1")
        };
        //I would use Any/Split/Contains
        var tuplets = users.Where(u => Filter.Any(y=> u.Item2.Split(';').Contains(y)));

        if (tuplets.Distinct().ToList().Count > 0)
        {
            foreach (var item in tuplets) Console.WriteLine(item.ToString());
        }
        else
        {
            Console.WriteLine("No results");
        }

除了其他答案之外,Contains扩展方法也可能非常适合您要执行的操作,如果您匹配一个值:

var result = list.Where(x => filter.Contains(x.Value));

否则,Any方法将接受委托:

var result = list.Where(x => filter.Any(y => y.Value == x.Value));