Linq选择包含所有包含标志的行并且没有排除标志

时间:2015-04-02 13:19:46

标签: c# linq

我有可以通过多对多连接表应用于多个ID的属性标志:

ID | Flag
---------
1  | C
2  | B
3  | B
3  | C
4  | A
5  | A
5  | C
6  | A
6  | B
7  | A
7  | B
7  | C

这转向:

1   C
2  B
3  BC
4 A
5 A C
6 AB
7 ABC

给定2个标志数组,Include和Exclude我想找到所有包含所有Include标志且没有Exclude标志的ID。

包含= [A,B],排除= [C]:结果ID = [6]

包含= [A],排除= [C]:结果ID = [4,6]

包含= [A],排除= []:结果ID = [4,5,6,7]

我想在Linq中使用它,理想情况下应该使用查询语法。

我已尝试创建此功能,但无法了解如何使用一组条件开始处理多个条目。

from row in data
where 
    include.Contains(row.Flag) &&
    !exclude.Contains(row.Flag)
select row.ID

2 个答案:

答案 0 :(得分:3)

Dictionary<int, string> flags = new Dictionary<int, string> { /* ... */ };
string[] includes = ["A", "B"];
string[] excludes = ["C"];
flags
    .GroupBy(f => f.Id)
    .Where(g =>
        includes.All(i => g.Any(f => f.Flag == i)) &&
        !excludes.Any(e => g.Any(f => f.Flag == e)))

答案 1 :(得分:2)

您需要按ID分组,然后检查每个组是否包含所有Include个标记,而不是Exclude个标记:

var q = Items.GroupBy(x => x.ID)
             .Where(g => (g.Select(x => x.Flag)
                           .Intersect(Include)
                           .Count() == Include.Count()) 

                         &&                        
                         (g.Select(x => x.Flag)
                           .Intersect(Exclude)
                           .Count() == 0))
             .Select(g => g.Key);

我正在使用Intersect检查每个组中Include / Exclude个标志的存在/不存在。

给出您的样本数据,例如:

string[] Include = new string[] { "A", "B" };
string[] Exclude = new string[] { "C" };

输出是:

[0] = 6
上述linq查询中使用的

Items对象是List

class Item
{
    public int ID {get; set;}
    public string Flag { get; set; }
}