假设我有一个课程如下......
public class IntGroup {
public string GroupName {get; set;}
public List<int> Integers {get; set;}
}
...我有几个实例,每个实例都包含一个整数集合。我想找到包含不同整数的最小组。
例如,如果我有以下组...
第1组包含1,2,3 第2组包含4,5,6 第3组包含4,5,9
...然后由于组1包含三个不在任何其他组中的整数,它本身就是一组最小的组(在本例中是一组)。第2组和第3组是另一组,因为你需要两个组在一起(因为它们都包含4和5),但它们不需要组1。
我想写一些C#代码,可以帮助我找到这些最小的组。这是我认为在Linq中可以非常优雅地解决的问题,但我无法弄清楚如何。
任何人都可以提供帮助吗?顺便说一句,这不是一个功课问题,我是一个51岁的程序员,希望解决一个更大问题的部分问题,即构建函数调用树,并希望找到树的不同部分。
感谢您提供任何帮助。
答案 0 :(得分:2)
首先定义这个类:
class ValueIEnumerableComparer<T> : IEqualityComparer<IEnumerable<T>>
{
public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
{
return x.SequenceEqual(y);
}
public int GetHashCode(IEnumerable<T> obj)
{
return obj.Sum(i => i.GetHashCode());
}
}
然后,您可以使用此链:
int[][] groups =
{
new[] {1, 2, 3},
new[] {4, 5, 6},
new[] {4, 5, 9}
};
var result = groups.
GroupBy(array => groups.
Where(other => array != other).
SelectMany(other => array.Intersect(other)),
new ValueIEnumerableComparer<int>()).
Select(g => g.ToArray()).
ToArray();
它的作用是按照交叉点对数组进行分组,然后只选择组中的数组。定义实现IEqualityComparer<IEnumerable<T>>
的类是必要的。我没有找到一种更好的方法来提取两个序列上的密钥,而没有定义比较它们的元素的比较器。它的GetHashCode()
方法并不真实,但适用于此示例。
它也可以很容易地适应你的情况,但我认为带一个普通的对于那些阅读问题的人来说会更有帮助。