genesUsingCrossover是List<List<double>>
。
我正在使用以下代码行来计算List<double>
中不同的List<List<double>>
:
int count = genesUsingCrossover.Distinct().Count();
,我不确定这是正确的。 genesUsingCrossover
中的元素数为1250,并且genesUsingCrossover.Distinct().Count()
返回1250,因此我假设它们都是不同的List。但是,在观察窗口中,我注意到第三和第四列表是相同的。
因此,我认为代码行不正确。有办法改善吗?并计算不同元素的数量?
答案 0 :(得分:3)
List<T>
不会覆盖Object.Equals
,因此两个List<double>
对象只有在引用相等时才被视为相等。 (Here是Distinct<T>()
的实现,如果您想看看它是如何工作的。)听起来好像您希望两个列表相等(如果组成它们的元素相等)。为此,您可以使用带有IEqualityComparer<T>
的{{3}},它将用来确定两个列表是否相等。因此,在您的情况下,您可以提供IEqualityComparer<List<double>>
的实现,以表达您的列表平等思想。
该实现的外观取决于您何时希望两个列表相等。例如,它们必须具有相同顺序的相同元素集,还是顺序不相关?关于堆栈溢出还有其他问题可以解释如何实现这两个问题。在任何一种情况下,请记住Distinct()
将多次调用您的实现,因此,算法必须具有良好的性能,这一点很重要。为此,可能值得问一问List<List<double>>
是否真的是您想要的数据结构,或者其他选择是否更适合。
答案 1 :(得分:1)
实际上,您没有定义两个列表被视为相等的条件。
这意味着.NET默认检查两个列表在内存中是否具有相同的引用,因为List
是reference type
很显然,每个列表都有他的记忆。因此,您的列表包含1205个元素,它返回的1205个元素与众不同。
作为您的描述,我认为您的标准是:2个包含相同元素的列表应该相等。
Distinct
可以收到IEqualityComparer
,所以这个想法是:为IEqualityComparer
实现List<double>
class NumberDoubles: IEqualityComparer<List<double>>
{
public bool Equals(List<double> x, List<double> y)
{
//Check whether the compared objects reference the same data.
if (Object.ReferenceEquals(x, y)) return true;
//Check whether any of the compared objects is null.
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
if (x.Count!= y.Count)
return false;
//Check whether the arrays' values are equal.
for(int i = 0; i < x.Count; i++){
if(x[i] != y[i])
return false;
}
// If got this far, arrays are equal
return true;
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public int GetHashCode(List<double> doubleArray)
{
//Check whether the object is null
if (Object.ReferenceEquals(doubleArray, null)) return 0;
//Calculate the hash code for the array
int hashCode = 0;
bool isFirst = true;
foreach(int i in doubleArray){
if(isFirst) {
hashCode = i;
isFirst = false;
}
else
{
hashCode = hashCode ^ i;
}
}
return hashCode;
}
}
和您的代码:
genesUsingCrossover.Distinct(new NumberDoubles());
答案 2 :(得分:0)
就像@Joe所说,您应该真的在想:“我真的需要List<List<double>>
听起来对我来说是不合适的结构。HashSet
可以与众不同(不是吗?完全取决于您的情况,但是通常每次有人看到HashSet
时,它都会发出希望唯一的提示,而List<List<double>>
不一定会表明这一点。
话虽如此,我建议您使用HashSet<List<double>>
using System;
using System.Collections.Generic;
using System.Linq;
public static class Program {
public static void Main() {
var hashSet = new HashSet<List<double>>(new ListComparer());
hashSet.Add(new List<double> { 1.2d, 1.5d });
hashSet.Add(new List<double> { 1.2d, 1.5d });
Console.Write(hashSet.Count);
}
public class ListComparer : IEqualityComparer<List<double>>
{
public bool Equals(List<double> x, List<double> y)
{
// your logic for equality
return true;
}
public int GetHashCode(List<double> obj)
{
int hash = 0;
unchecked {
foreach(var d in obj) {
hash += d.GetHashCode();
}
}
return hash;
}
}
}
请记住,Equals
方法将被调用很多次,因此,考虑到一些性能方面的考虑可能会很好。