我正在寻找可以执行以下操作的Linq查询:
对于List中的每个对象,检查是否有任何对象将2个字段设置为相同的值
对于标识的每个重复集,检查第三个字段是否与其中任何一个字段不同
如果满足#1和#2,则返回true(或+计数,只是查看数据是否重复的方式)
以下是满足所需搜索标准的对象示例:
oObject1 { data1 = "cat", data2 = "dog", data3 = "DE" }
oObject2 { data1 = "cat", data2 = "dog", data3 = "FR" }
以下内容不得作为“重复”返回:
oObject3 { data1 = "cat", data2 = "dog", data3 = "DE" }
oObject4 { data1 = "cat", data2 = "dog", data3 = "DE" }
到目前为止,我可以使用以下查询获取重复项:
var lDuplicates = lstObjects.GroupBy(x => new { x.data1, x.data2})
.Where(x => x.Skip(1).Any());
我需要的是扩展上面的查询以检查data3也不同的那些。有没有人知道如何实现这一目标?
答案 0 :(得分:2)
你很亲密。您需要的是扩展每个组中的序列,并通过 data3 从中创建新组。
当查询趋于复杂时,我使用查询语法。如果我做对了,这可能是正确的方向。
var queryResult =
from obj in lstObjects
group obj by new { obj.data1, obj.data2 } into outerGroup
where outerGroup.Skip(1).Any()
let additionalCheckGroup = (from g in outerGroup
group g by g.data3 into innerGroup
where innerGroup.Skip(1).Any() == false
select innerGroup)
from innerGroup in additionalCheckGroup
select new
{
outerKey = outerGroup.Key,
innerKey = innerGroup.Key,
};
查询将返回有关 data3 NOT 满足的出版物组的信息,以及其余的空序列。
所以对于第一个例子:它会产生 - >
[0]: { outerKey = {{ data1 = cat, data2 = dog }}, innerKey = "FR" }
[1]: { outerKey = {{ data1 = cat, data2 = dog }}, innerKey = "DE" }
对于第二个例子:它会产生 - > empty sequence.
注意:结果是平的,这意味着它将返回元素序列而非组,我不确定您期望的结果。
如果您对评论中有任何疑问,请与我们联系。
答案 1 :(得分:0)
使用您现在拥有的结果,而不是检查是否有更多项目(skip1-any),您可以检查是否有任何项目不等于第一项的data3
。
在使用第一个data3
分配变量的帮助下,在查询语法中可以更轻松地完成此操作:
var lDuplicates = from x in lstObjects
group x by new { x.data1, x.data2} into g //g now contains groups with unique data1 and data3 objects
let first = g.First().data3 //assign the first data3 to an intermediate variable
where g.Skip(1).Any(x=>x.data3 != first) //check if there are any entries that have an deviating data3
select g;
以上选择了与条件对应的所有组(如果需要,可以在同一查询中展平)。
但这也意味着一个群体可以包含2" DE" s,只要至少有一个没有" DE"。不确定这是否是要求。要唯一地获得所有对象(展平):
var lDuplicates = from x in lstObjects
group x by new { x.data1, x.data2} into g //g now contains groups with unique data1 and data3 objects
let d3 = g.Select(x=>x.data3).Distinct().ToList() //a list of unique data3 properties
where d3.Count() > 1 //only with more than one unique data3
from data3 in d3
select new{g.Key.data1,g.Key.data2, data3}; //create a new object
注意,上面创建了一个 new 对象,因为对于多个匹配项,要使用哪个对象? (它可以具有比data1,data2和data3更多的属性)。要根据&data 39" -group:
选择第一个对象 var lDuplicates = from x in lstObjects
group x by new { x.data1, x.data2} into g //g now contains groups with unique data1 and data3 objects
let d3 = g.GroupBy(x=>x.data3) //create a subgroup for data3 (per group g)
where d3.Count() > 1 //only with multiple data3
from gx in d3 //flatten d3 groups
select gx.First(); //select the first object in the d3 subgroup