我有一个对象列表。这些对象由自定义类组成,该类基本上包含两个字符串字段String1
和String2
。
我需要知道的是,如果这些字符串中的任何字符串在该列表中重复。所以我想知道objectA.String1 == objectB.String1
,ObjectA.String2 == ObjectB.String2
,ObjectA.String1 == ObjectB.String
“还是ObjectA.String2 == ObjectB.String1
。
另外,我想将包含重复字符串的每个对象标记为具有重复字符串(对象上有bool HasDuplicate
)。
因此,当重复检测已经运行时,我想简单地按照这样的方式遍历列表:
foreach (var item in duplicationList)
if (item.HasDuplicate)
Console.WriteLine("Duplicate detected!");
这似乎是用LINQ解决的一个很好的问题,但我不能为我的生活找出一个好的查询。所以我用'好老'的foreach解决了它,但我仍然对LINQ版本感兴趣。
答案 0 :(得分:12)
这是一个完整的代码示例,应该适合您的情况。
class A
{
public string Foo { get; set; }
public string Bar { get; set; }
public bool HasDupe { get; set; }
}
var list = new List<A>
{
new A{ Foo="abc", Bar="xyz"},
new A{ Foo="def", Bar="ghi"},
new A{ Foo="123", Bar="abc"}
};
var dupes = list.Where(a => list
.Except(new List<A>{a})
.Any(x => x.Foo == a.Foo || x.Bar == a.Bar || x.Foo == a.Bar || x.Bar == a.Foo))
.ToList();
dupes.ForEach(a => a.HasDupe = true);
答案 1 :(得分:4)
这应该有效:
public class Foo
{
public string Bar;
public string Baz;
public bool HasDuplicates;
}
public static void SetHasDuplicate(IEnumerable<Foo> foos)
{
var dupes = foos
.SelectMany(f => new[] { new { Foo = f, Str = f.Bar }, new { Foo = f, Str = f.Baz } })
.Distinct() // Eliminates double entries where Foo.Bar == Foo.Baz
.GroupBy(x => x.Str)
.Where(g => g.Count() > 1)
.SelectMany(g => g.Select(x => x.Foo))
.Distinct()
.ToList();
dupes.ForEach(d => d.HasDuplicates = true);
}
你基本上做的是
此解决方案优于Winston Smith解决方案的一些优点是:
答案 2 :(得分:0)
首先,如果您的对象尚未具有HasDuplicate属性,请声明一个实现HasDuplicateProperties的扩展方法:
public static bool HasDuplicateProperties<T>(this T instance)
where T : SomeClass
// where is optional, but might be useful when you want to enforce
// a base class/interface
{
// use reflection or something else to determine wether this instance
// has duplicate properties
return false;
}
您可以在查询中使用该扩展方法:
var itemsWithDuplicates = from item in duplicationList
where item.HasDuplicateProperties()
select item;
与普通属性相同:
var itemsWithDuplicates = from item in duplicationList
where item.HasDuplicate
select item;
或
var itemsWithDuplicates = duplicationList.Where(x => x.HasDuplicateProperties());
答案 3 :(得分:0)
帽子提示https://stackoverflow.com/a/807816/492
var duplicates = duplicationList
.GroupBy(l => l)
.Where(g => g.Count() > 1)
.Select(g => {foreach (var x in g)
{x.HasDuplicate = true;}
return g;
});
duplicates
是一次性的,但它会以较少的枚举为您提供。
答案 4 :(得分:-1)
var dups = duplicationList.GroupBy(x => x).Where(y => y.Count() > 1).Select(y => y.Key);
foreach (var d in dups)
Console.WriteLine(d);