1

我有一个数组数组-有关使用 VSTO 在 Excel 中进行选择的信息,其中每个元素表示开始和结束选择位置。

例如,

int[][] selection = {
new int[] { 1 }, // column A
new int[] { 6 }, // column F
new int[] { 6 }, // column F
new int[] { 8, 9 } // columns H:I
new int[] { 8, 9 } // columns H:I
new int[] { 12, 15 } // columns L:O
};

你能帮我找到一种方法,也许使用 LINQ 或扩展方法,来删除重复的元素吗?我的意思是:FFH:IH:I,等等。

4

2 回答 2

3

如果您想使用纯 LINQ/扩展方法解决方案,那么您需要IEqualityComparer为数组/序列定义自己的实现。(除非我遗漏了一些明显的东西,否则 BCL 中没有预先存在的数组或序列比较器)。然而,这并不难——这是一个应该很好地完成工作的例子:

public class SequenceEqualityComparer<T> : IEqualityComparer<IEnumerable<T>>
{
    public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
    {
        return Enumerable.SequenceEqual(x, y);
    }

    // Probably not the best hash function for an ordered list, but it should do the job in most cases.
    public int GetHashCode(IEnumerable<T> obj)
    {
        int hash = 0;
        int i = 0;
        foreach (var element in obj)
            hash = unchecked((hash * 37 + hash) + (element.GetHashCode() << (i++ % 16)));
        return hash;
    }
}

这样做的好处是您可以简单地调用以下命令来删除任何重复的数组。

var result = selection.Distinct(new SequenceEqualityComparer<int>()).ToArray();

希望有帮助。

于 2009-03-31T16:19:04.153 回答
0

首先,您需要一种比较整数数组的方法。要将它与框架中的类一起使用,您可以通过创建 EquailtyComparer 来实现。如果数组总是排序的,那很容易实现:

public class IntArrayComparer : IEqualityComparer<int[]> {

    public bool Equals(int[] x, int[] y) {
        if (x.Length != y.Length) return false;
        for (int i = 0; i < x.Length; i++) {
            if (x[i] != y[i]) return false;
        }
        return true;
    }

    public int GetHashCode(int[] obj) {
        int code = 0;
        foreach (int value in obj) code ^= value;
        return code;
    }

}

现在您可以使用整数数组作为 HashSet 中的键来获取唯一数组:

int[][] selection = {
    new int[] { 1 }, // column A
    new int[] { 6 }, // column F
    new int[] { 6 }, // column F
    new int[] { 8, 9 }, // columns H:I
    new int[] { 8, 9 }, // columns H:I
    new int[] { 12, 15 } // columns L:O
};

HashSet<int[]> arrays = new HashSet<int[]>(new IntArrayComparer());
foreach (int[] array in selection) {
    arrays.Add(array);
}

HashSet 只是丢弃了重复值,因此它现在包含四个整数数组。

于 2009-03-31T16:27:47.347 回答