Pergunta

I têm uma matriz de matrizes - informações sobre selecção no Excel usando VSTO, onde cada um dos meios de elementos posições inicial e selecção final

.

Por exemplo,

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
};

Você poderia me ajudar a encontrar uma maneira, talvez usando métodos LINQ ou extensão, para remover elementos duplicados? Quero dizer:. F e F, H:I e H:I, etc

Foi útil?

Solução

Se você quiser usar uma solução pura método LINQ / extensão, então você precisa definir sua própria implementação de IEqualityComparer para matrizes / sequências. (A menos que eu estou faltando algo óbvio, não há pré-existente matriz ou seqüência comparer na BCL). Isso não é muito difícil no entanto - aqui está um exemplo de um que deve fazer o trabalho muito bem:

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;
    }
}

A vantagem disso é que você pode, então, basta ligar para o seguinte para remover quaisquer matrizes duplicados.

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

Espero que ajude.

Outras dicas

Primeiro você precisa encontrar uma maneira de comparar os arrays de inteiros. Para usá-lo com as classes no quadro, você faz isso, fazendo uma EquailtyComparer. Se as matrizes são sempre classificadas, que é bastante fácil de implementar:

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;
    }

}

Agora você pode usar uma matriz de inteiros como chave em um HashSet para obter as matrizes únicas:

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);
}

O HashSet apenas joga fora valores duplicados, por isso agora contém quatro arrays de inteiros.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top