我正在尝试开发一个LINQ查询,它将识别具有重复值的对象。我只需要多值属性中的字符串与另一个对象上相同属性中的字符串匹配且“name”值不匹配的对象。
我试图使用以下代码,但它不起作用,因为它似乎不可能在子查询中使用“o”变量。
myList.Where(o => myList.Any(a => a.name != o.name && a.multival.Any(p => o.multival.Contains(p))))
为什么甚至使用linq呢?它会令人费解并且难以阅读。我会用嵌套的for循环来解决这个问题:
var listOfDuplicates = new IEnumerable<YourObjectType>();
foreach (var a in myList)
{
foreach (var b in myListb)
{
if (a.multival == b.multival && a.name != b.name)
listOfDuplicates.Add(a);
}
}
在回应注释时,这就是如何实现退出类似于LINQs FirstOrDefault()的方法以及在X量匹配后退出的其他方法:
Public IEnumerable<YourObjectType> FindDuplicates(IEnumerable<YourObjectType> myList, int maxDupes)
{
var listOfDuplicates = new IEnumerable<YourObjectType>();
foreach (var a in myList)
{
foreach (var b in myListb)
{
if (a.multival == b.multival && a.name != b.name)
listOfDuplicates.Add(a);
if (listOfDuplicates.length == maxDupes)
return listOfDuplicates;
}
}
return listOfDuplicates;
}
您的查询实际上应该“正常工作”,但如果列表大小特别大,则查询效率不高。如果您遇到麻烦,请检查以确保您没有任何拼写错误。如果您在运行时遇到问题,请在变量和属性上添加一些空值检查。本答案的其余部分是指导您如何利用Linq更好地进行查询。
鉴于您尝试编写的查询,我将推断以下内容与您的类结构的相关部分非常接近,尽管我使用的名称与“multival”不同。
class Foo
{
public string Name { get; set; }
public string[] Attributes { get; set; }
}
然后给出一个大致像这样的对象列表
var mylist = new List<Foo>
{
new Foo { Name = "Alpha", Attributes = new[] { "A", "B", "C" } },
new Foo { Name = "Bravo", Attributes = new[] { "D", "E", "F" } },
new Foo { Name = "Charlie", Attributes = new[] { "G", "H", "A" } }
};
为了根据属性的任何匹配查找与任何其他对象匹配的对象,我将使用Linq来处理它:
var part1 = from item in mylist
from value in item.Attributes
select new { item, value };
var query = (from pairA in part1
join pairB in part1 on pairA.value equals pairB.value
where pairA.item.Name != pairB.item.Name
select pairA.item)
.Distinct(); // ToList() to materialize, as necessary
如果你通过你选择的编辑器运行它并探索part2
的内容,你会期望看到基于“A”的共享属性的对象“Alpha”和“Charlie”。
如果初始列表的大小很重要(例如,您的列表包含10,000个元素而不是3个元素),这种方法应该比嵌套的foreach更好地扩展,这正是您最初的方法。