我使用此方法创建一些数组并将它们存储在列表块中:
private void CreateBlocks()
{
if (size == 1)
{
blocks.Add(pos);
}
else if (orientation == "vert")
{
for (int i = 0; i < size; i++)
{
blocks.Add(new int[]{pos[0] + i, pos[1]});
}
}
else
{
for (int i = 0; i < size; i++)
{
blocks.Add(new int[] { pos[0], pos[1] + i });
}
}
}
我尝试使用此代码在shipsPos
列表中存储块列表数组(如果shipsPos
中不存在任何数组:
private void AddShips(int numberOfShips)
{
while (numberOfShips > 0)
{
Ship ship = new Ship();
if (!shipsPos.Intersect(ship.Blocks).Any())
{
ships.Add(ship);
shipsPos.AddRange(ship.Blocks);
shipTypes[ship.Size] += 1;
numberOfShips--;
}
}
}
Ship
是CreateBlocks
方法所属的类。我的问题是,即使shipsPos
中已经存在一个数组,它也会被添加到列表中。我究竟做错了什么?
答案 0 :(得分:4)
通过引用比较数组,以便具有相同元素的两个数组不等于相等。因此.Intersect(...)
将它们视为单独的数组。
试试这段代码:
var xs = new [] { new [] { 1, 2 }, new [] { 3, 4 } };
var ys = new [] { new [] { 1, 2 }, new [] { 5, 6 } };
var zs = xs.Intersect(ys); // 0 elements!
这表明.Intersect(...)
未选择数组作为元素。
要使.Intersect(...)
能够使用嵌套数组,您需要实现自己的IEqualityComparer<T[]>
。这是一个简单的问题:
public class ArrayComparer<T> : IEqualityComparer<T[]>
{
public bool Equals(T[] ts0, T[] ts1)
{
return ts0.SequenceEqual(ts1);
}
public int GetHashCode(T[] ts)
{
return ts.Aggregate(0, (a, t) => (a >> 2) + t.GetHashCode());
}
}
现在你可以这样做:
var zs = xs.Intersect(ys, new ArrayComparer<int>()); // 1 element!