为什么 Distinct (Linq) 在 int[] 列表中不起作用?
Why doesn't Distinct (Linq) work in a List of int[]?
这个方法是我写的。它应该 return 整数数组中的所有三元组 [a, b, c],其中 a ^ 2 + b ^ 2 = c ^ 2.
public static List<int[]> AllTripletsThatFulfilla2b2c2Equality(int[] n)
{
var combinations = from i in n
from j in n
from p in n
select new int[][] {new int[]{ i, j, p }, new int[] {p, j, i}, new int[] {i, p, j}};
return combinations.Where(x => x.Length == x.Distinct().Count() && Math.Pow(x[0], 2) + Math.Pow(x[1], 2) == Math.Pow(x[2], 2)).Distinct().ToList();
}
Distinct 不起作用。
我尝试了其他几种写法,包括
public static List<int[]> AllTripletsThatFulfilla2b2c2Equality(int[] n)
{
var combinations = from i in n
from j in n
from p in n
select new[] { i, j, p };
combinations = combinations.ToList();
Func<int[], List<int[]>> combo = x =>
{
List<int[]> list = new List<int[]>();
list.Add(x);
if (!combinations.Contains(new [] { x[0], x[2], x[1] }))
{
list.Add(new[] { x[0], x[2], x[1] });
}
if (!combinations.Contains(new[] { x[2], x[1], x[0] }))
{
list.Add(new[] { x[2], x[1], x[0] });
}
list.Add(new [] { x[0], x[2], x[1] });
list.Add(new [] { x[2], x[1], x[0] });
return list;
};
return combinations.SelectMany(combo).Distinct().Where(x => x.Length == x.Distinct().Count() && Math.Pow(x[0], 2) + Math.Pow(x[1], 2) == Math.Pow(x[2], 2)).ToList();
}
甚至为 Distinct 添加了一个比较器:
public class TripletComparer : IEqualityComparer<int[]>
{
public bool Equals(int[] x, int[] y)
{
return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];
}
public int GetHashCode(int[] obj)
{
return obj.GetHashCode();
}
}
测试结果相同,这个:
Assert.Equal() Failure
Expected: List<Int32[]> [[3, 4, 5], [4, 3, 5]]
Actual: List<Int32[]> [[3, 4, 5], [3, 4, 5], [4, 3, 5], [4, 3, 5], [4, 3, 5], ...]
不知何故,它没有看到有重复的项目。有谁知道为什么以及如何解决它?
您的 GetHashCode
- 实施似乎很奇怪。通常,您会根据在实际 Equals
-check 中使用的完全相同的成员来计算哈希码。否则 Distinct
可能甚至不会调用您的 Equals
方法。
public bool Equals(int[] x, int[] y)
{
return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];
}
public int GetHashCode(int[] obj)
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + obj[0].GetHashCode();
hash = hash * 23 + obj[1].GetHashCode();
hash = hash * 23 + obj[2].GetHashCode();
return hash;
}
免责声明:哈希码代码改编自。
这个方法是我写的。它应该 return 整数数组中的所有三元组 [a, b, c],其中 a ^ 2 + b ^ 2 = c ^ 2.
public static List<int[]> AllTripletsThatFulfilla2b2c2Equality(int[] n)
{
var combinations = from i in n
from j in n
from p in n
select new int[][] {new int[]{ i, j, p }, new int[] {p, j, i}, new int[] {i, p, j}};
return combinations.Where(x => x.Length == x.Distinct().Count() && Math.Pow(x[0], 2) + Math.Pow(x[1], 2) == Math.Pow(x[2], 2)).Distinct().ToList();
}
Distinct 不起作用。
我尝试了其他几种写法,包括
public static List<int[]> AllTripletsThatFulfilla2b2c2Equality(int[] n)
{
var combinations = from i in n
from j in n
from p in n
select new[] { i, j, p };
combinations = combinations.ToList();
Func<int[], List<int[]>> combo = x =>
{
List<int[]> list = new List<int[]>();
list.Add(x);
if (!combinations.Contains(new [] { x[0], x[2], x[1] }))
{
list.Add(new[] { x[0], x[2], x[1] });
}
if (!combinations.Contains(new[] { x[2], x[1], x[0] }))
{
list.Add(new[] { x[2], x[1], x[0] });
}
list.Add(new [] { x[0], x[2], x[1] });
list.Add(new [] { x[2], x[1], x[0] });
return list;
};
return combinations.SelectMany(combo).Distinct().Where(x => x.Length == x.Distinct().Count() && Math.Pow(x[0], 2) + Math.Pow(x[1], 2) == Math.Pow(x[2], 2)).ToList();
}
甚至为 Distinct 添加了一个比较器:
public class TripletComparer : IEqualityComparer<int[]>
{
public bool Equals(int[] x, int[] y)
{
return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];
}
public int GetHashCode(int[] obj)
{
return obj.GetHashCode();
}
}
测试结果相同,这个:
Assert.Equal() Failure
Expected: List<Int32[]> [[3, 4, 5], [4, 3, 5]]
Actual: List<Int32[]> [[3, 4, 5], [3, 4, 5], [4, 3, 5], [4, 3, 5], [4, 3, 5], ...]
不知何故,它没有看到有重复的项目。有谁知道为什么以及如何解决它?
您的 GetHashCode
- 实施似乎很奇怪。通常,您会根据在实际 Equals
-check 中使用的完全相同的成员来计算哈希码。否则 Distinct
可能甚至不会调用您的 Equals
方法。
public bool Equals(int[] x, int[] y)
{
return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];
}
public int GetHashCode(int[] obj)
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + obj[0].GetHashCode();
hash = hash * 23 + obj[1].GetHashCode();
hash = hash * 23 + obj[2].GetHashCode();
return hash;
}
免责声明:哈希码代码改编自。