Pergunta

Estou escrevendo minha própria referência do LINQ, mas estou obtendo problemas com algumas das implementações de operadoras mais complicadas.

Há uma implementação de junção que leva um IequalityCompare, que estou ficando louco.

Estou tentando entender primeiro antes de escrever (obviamente)

Image essas duas listas:

List<string> initials = new List<string> {"A", "B", "C", "D", "E"};

List<string> words = new List<string> {"Ant", "Crawl", "Pig", "Boat", "Elephant", "Arc"};

Nada estranho aqui. Quero participar das duas listas da inicial, algo como:

Inicial = uma palavra = formig
Inicial = um word = arco
Inicial = b word = barco
...

Eu preciso de um comparador, escrevi isso:

public class InitialComparator : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {
        return x.StartsWith(y);
    }

    public int GetHashCode(string obj)
    {
        return obj[0].GetHashCode();
    }
}

A junção em si:

var blah = initials.Join(words,
                                  initial => initial,
                                  word => word,
                                  (initial, word) =>
                                  new {Initial = initial, Word = word},
                                  new InitialComparator());

É a primeira vez que estou usando hashcodes, depois de uma boa sessão de depuração, vejo que cada palavra vá para o comparador e observe seu código de hash, se outra palavra tiver o mesmo hashcode que ele chama é igual.

Como eu quero comparar apenas a inicial, pensei que só preciso da primeira letra Hash (estou errado?)

O problema é que isso não está funcionando corretamente. Diz que "formiga" e "arco" são iguais, ok, está comparando cada palavra na mesma lista ou não, mas adiciona apenas a última palavra que encontra, neste caso arco, ignorar a formiga e a formiga é igual a "a" a " também...

Se eu colocar "Ant" e "Ant", acrescente os dois.

Em suma, qual é a maneira de fazer algo assim? Eu sei que estou fazendo algo errado.

Obrigada.

Foi útil?

Solução

Como mencionado crocante, tente x [0] == y [0] em vez de x.startswith (y); Isso funcionou para mim.

Outras dicas

Na verdade, você não precisa de seu próprio comparador de igualdade, basta participar da carta individual como assim:

var mine = from i in initials
     join w in words on i[0] equals w[0]
     select new {
          Initial = i,
          Words = w
     };

Não sei por que você está vendo esse comportamento, mas acho que "SelectMany" seria uma abordagem mais direta e (mais importante) tem o comportamento que você deseja:

var blah =
    from word in words
    from initial in initials
    where (word.StartsWith(initial))
    select new { Initial = initial, Word = word };

Prefiro usar a sintaxe de compreensão sempre que possível. "SelectMany" é chamado quando houver múltiplos "de" cláusulas em uma consulta de compreensão.

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