我试图按部门过滤用户。过滤器可能包含多个部门,用户可能属于多个部门(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)
我希望它返回的是: Meyer,Green,Brown 。如果将Filter
设置为"Dep1;Dep2"
,我会想要进行比较并找到* Meyer,Jackson,Green,Brown&#34; (以及不同的,因为我不想要绿色两次)。如果Filter
设置为"Dep2"
,我只想拥有 Jackson,Green 。我也玩过.Split(';')
,但它让我无处可去。
我有道理吗?我有具有单个/多个部门的用户,并希望过滤这些部门。在我的输出中,我希望拥有指定部门的所有用户。 LINQ-magic在我身上并不那么强大。
答案 0 :(得分:1)
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");
}
答案 1 :(得分:1)
由于string
实施IEnumerable
,您现在所做的就是Intersect
上的IEnumerable<char>
(即您正在检查每封信中的;
字符串)。您需要在Item2
和Filter
上分开var tuplets = users.Where(u =>
u.Item2.Split(new []{';'})
.Intersect(Filter.Split(new []{';'}))
.Any());
并与之相交。
{{1}}
答案 2 :(得分:1)
除了其他答案之外,Contains
扩展方法也可能非常适合您在匹配某个值时尝试执行的操作:
var result = list.Where(x => filter.Contains(x.Value));
否则,Any
方法将接受委托:
var result = list.Where(x => filter.Any(y => y.Value == x.Value));