Um engenheiro de suporte uma vez me perguntou por que quarenta clientes haviam recebido um e-mail de renovação duas vezes A resposta levou uma hora para ser encontrada e era completamente mundana: a lista de campanha havia sido montada colando uma exportação sob outra, e quarenta endereços existiam em ambas Ninguém havia verificado, porque verificar significava ou olhar duas mil linhas ou escrever a VLOOKUP essa metade da equipe não confiava & #39; T. Então ninguém verificou, e as mesmas quarenta pessoas foram informadas duas vezes que seu cartão estava prestes a ser cobrado.
Essa é a forma deste problema Reconciliar duas listas é uma das coisas mais comuns que alguém faz com dados, e ele' é chato o suficiente para que as pessoas pulem ou façam mal. O instinto geralmente é buscar uma ferramenta de comparação, colar as duas listas e apertar os olhos na saída colorida - o que falha imediatamente, porque um diferencial responde a uma pergunta que você fez & #39; ou você vai a uma planilha e começa a montar MATCH/COUNTIF fórmulas, que funciona mas leva dez minutos e produz um artefato você'nunca reutilizará.
A operação que você realmente deseja tem um nome e it' s mais antigo do que qualquer uma das ferramentas: definir aritmética Intersecção, diferença, união. Eu construo [Toolz.dev] (/e coloco um navegador baseado ferramenta de comparação de listas lá, mas este guia é sobre os conceitos abaixo - por que a ordem deve ser ignorada, em que caso dobrar silenciosamente quebra e como escolher entre isso e uma diferença.
tl;dr: Para comparar duas listas, trate cada uma como um conjunto não ordenado e calcule a interseção (itens em ambos), as duas diferenças (itens apenas em A, itens apenas em B) e as duplicatas dentro de cada lista Ignorar a ordem inteiramente - um diff de linha é a ferramenta errada porque ele & #39; s posicional, então reordenar uma lista faz com que quase todas as linhas pareçam alteradas Pasta caso para identificadores como e-mails, mas preservar o texto original na saída, aparar espaços em branco antes de comparar, e fazê-lo no navegador, uma vez que as listas que as pessoas reconciliam são geralmente dados do cliente.
Quais perguntas a comparação de duas listas realmente responde?
Depois de ver as operações nomeadas, as formas tornam-se óbvias Dada a lista A e a lista B:
- Intersecção- o que' s em ambos? quais assinantes também estão pagando clientes. Quais dos SKUs do mês passado' s ainda estão neste mês' s catálogo.
- Um menos B- o que & #39; s apenas em A? quais usuários no CRM nunca fizeram isso em faturamento Quais arquivos existem localmente, mas não no servidor.
- B menos A- o que's apenas em B? A mesma pergunta na outra direção, e it's a diferente pergunta. Faltar-de-faturamento e faltar-de-CRM são dois bugs distintos com duas causas distintas.
- Diferença simétrica- o que' s em exatamente uma lista? a união de ambas as diferenças: tudo o que não conseguiu corresponder, independentemente da direçãoEste é o & quot; what' s fora de sincronia?" pergunta.
- União- tudo de qualquer lista, desduplicado A mesclagem, feita corretamente.
- Duplica dentro de uma lista- o que's repetido dentro de A sozinho? Este é ' t uma comparação em tudo, mas ele' s sempre a pergunta que você acaba por ter necessário, porque ele' s o que causa duplo-envios e duplo-faturamento.
Vale a pena separar esse último. A correspondência entre listas e a duplicação dentro da lista são independentes: um endereço pode aparecer duas vezes em A e também aparecem em B. Ferramentas que relatam apenas resultados de listas cruzadas perdem a falha que custa dinheiro.
Tudo aqui mapeia diretamente nas operações que você já conhece do SQL - INTERSECT, EXCEPT, UNION- e em fórmulas de planilhas O valor de uma ferramenta dedicada é & #39; t que ela faz algo que você pode & #39; t; it & #39; s que todas as seis respostas aparecem de uma pasta, em vez de seis fórmulas diferentes.
Por que uma ferramenta diff é a escolha errada para comparar listas?
Este é o erro que mais vejo, e vale a pena ser preciso sobre ele e #39; porque & quot; compare duas listas e quot; e " diferenciar dois arquivos e quot; soa como sinônimos.
Um diff é posicional. Algoritmos diferentes calculam o script de edição mínimo - a sequência mais curta de inserções e exclusões que transforma uma sequência na outra. That' é o modelo certo para código-fonte e prosa, onde está a linha 40 seguindo a linha 39 significativo. Mova uma função e um diff informa corretamente que você moveu uma função.
Uma lista não tem ordem significativa. A linha 300 em sua exportação de CRM não tem nenhuma relação com a linha 300 em sua exportação de faturamento. Eles e #39; são dois sacos de itens que por acaso estão escritos em qualquer sequência que o banco de dados retorne.
Alimente dados não ordenados para um algoritmo posicional e você obter ruído Pegue duas listas com conteúdos idênticos, classifique um deles, e diff-los:
List A List B
alice bob
bob alice
carol carol
Um diff relata isso alice foi removido e adicionado novamente, ou isso bob movido - alguma rotatividade proporcional à diferença entre os dois. A resposta correta é nada mudou. Cada item está em ambas as listas Os conjuntos são iguais Um diff can' t dizer que porque é & #39; t perguntando sobre a adesão.
A tabela de comparação, uma vez que as ferramentas se sobrepõem genuinamente nas mentes das pessoas que procuram ambos:
| Lista Comparar | Diferença de texto | |
|---|---|---|
| Modelo | Conjunto não ordenado de itens | Sequência ordenada de linhas |
| Ordem importa? | Não - reordenar livremente, resultados idênticos | Sim - reordenar shows como alterações |
| Respostas | Filiação: em ambos, apenas A, apenas B, duplicado | Edições: o que inserir/excluir para transformar A em B |
| Itens duplicados | Relatado explicitamente como um grupo | Só mais linhas |
| bom para | Reconciliando exportações, listas de e-mail, IDs, SKUs, estoques | Código fonte, prosa, arquivos de configuração, qualquer coisa onde a posição seja significado |
| Mau para | Comparando duas versões de um documento | Qualquer lista onde a ordem de classificação é arbitrária |
A regra: se você & #39; ficar igualmente satisfeito com a lista classificada de forma diferente, você deseja uma comparação definida. Se reordenar as linhas seria uma mudança real que vale a pena relatar, você quer o Verificador de diff de texto. Para dados estruturados com aninhamento em vez de linhas planas, nada se aplica - isso' s o que o json diff é para, uma vez que se compara por caminho principal e não por linha ou por adesão.
Como deve funcionar a sensibilidade ao caso?
Esta é a opção que as pessoas deixam por padrão e depois erram silenciosamente, então vale a pena pensar nisso uma vez.
A correspondência sem distinção entre maiúsculas e minúsculas é o padrão certo para os dados que a maioria das pessoas compara Endereços de e-mail, nomes de usuário, nomes de domínio, códigos de produtos, códigos de países - estes são convencionalmente insensíveis a maiúsculas e minúsculas na prática e [email protected] e [email protected] são a mesma pessoa em todos os sistemas que importam.
Aí' é uma ressalva pedante aqui de que' vale a pena saber porque ele' ocasionalmente suporta carga: por RFC 5321, a parte de domínio de um endereço de e-mail não diferencia maiúsculas de minúsculas, mas o local parte - tudo antes do @- é formalmente case-sensitive e deixado para o servidor de correio de recepção para interpretar Então [email protected] e [email protected] poderia, em princípio, ser caixas de correio diferentes Na prática, essencialmente cada grande provedor trata-los como idênticos, e se você & #39;re des-duplicating uma lista de discussão você deve absolutamente dobrar caso Mas se você & #39;re depuração por que um endereço específico salta, que & #39; é o tipo de detalhe que acaba por importar.
Caso-sensível a correspondência é correta para qualquer coisa onde o caso carrega informações: caminhos de arquivos Linux, strings base64, hashes, tokens JWT, chaves de API, Git SHAs, a maioria dos identificadores de programação O caso dobrável em uma lista de hashes de senha mesclaria valores distintos e daria uma resposta confiantemente errada.
O detalhe da implementação que importa mais do que a própria opção: caso de dobra para correspondência, mas mostrar o texto original. Se você colar [email protected] e a ferramenta informa ' s em ambas as listas, deve ser devolvido [email protected]- não [email protected]. A redução da saída corrompe silenciosamente seus dados no caminho, e como o próximo passo usual é colar o resultado em outro lugar, essa corrupção viaja A ferramenta mantém a forma vista pela primeira vez de cada item e combina em uma chave dobrada nos bastidores, então o que sai é o que você coloca.
O espaço em branco merece o mesmo tratamento e fica menos pensado Copie uma coluna de uma planilha ou divida uma linha como a, b, c nas vírgulas, você recebe itens que transportam espaços principais. [email protected] e [email protected] são strings diferentes e endereços idênticos. O corte está ativado por padrão por esse motivo, e é a opção você e #39; a opção você e #39;d percebem que faltam cerca de trinta segundos após o uso real.
Que separador devo usar?
O padrão é um item por linha, que é o que você obtém colando uma coluna de planilha - a área de transferência entrega valores separados por nova linha, portanto, uma coluna de e-mails do Excel, Planilhas do Google ou uma exportação CSV aparece sem reformatação.
Os outros separadores cobrem dados que chegam já em linha Vírgula para uma única linha CSV ou uma matriz copiada Ponto e vírgula para o Outlook e convenção older-Windows para listas de endereços Espaço para saída de shell - ls, git diff --name-only canalizado tr, qualquer coisa delimitada pelo espaço Tab for a row colado a partir de uma planilha horizontalmente em vez de verticalmente.
Uma coisa a notar: dividir em vírgulas é não análise CSV. Um campo CSV real pode conter uma vírgula dentro das aspas, e uma divisão ingênua irá rasgar "Smith, Jane" em dois itens. Se você' estiver retirando uma coluna de um arquivo CSV genuíno com campos citados, execute-o através do Visualizador de CSV primeiro - ele implementa as regras reais de cotação RFC 4180 - em seguida, copie a coluna que você deseja Para uma lista plana de e-mails ou IDs sem vírgulas incorporadas, dividir é bom e isso não & #39; t vem acima.
As entradas vazias são descartadas por padrão, porque elas & #39; são quase sempre artefatos: uma nova linha à direita no final de uma pasta, uma linha em branco em uma planilha, uma vírgula dupla Uma string vazia é & #39; t um item em qualquer lista com o qual você realmente se importa A opção existe se você & #39; está caçando especificamente linhas em branco em uma exportação, o que é uma coisa real, embora incomum, a desejar.
Como é que a escala de comparação?
A abordagem ingênua para comparar duas listas é um loop aninhado: para cada item em A, digitalize todos os B. That' s O(n×m) e it' s multa para cem itens e inutilizável para cinquenta mil, onde você're fazendo 2,5 bilhões de comparações de strings.
A abordagem correta indexa cada lista em um mapa hash chaveado pela chave de comparação - a forma dobrada e aparada do item - com o valor sendo o original visto pela primeira vez Construir cada índice é uma passagem linear Então cada pergunta se torna uma pesquisa de tempo constante por item: esta chave está no mapa B & #39; s? toda a comparação é O (n+m), o que significa que vinte mil itens de cada lado são quarenta mil operações hash e são concluídos mais rápido do que o navegador pode repintar.
O mesmo índice dá duplicatas gratuitamente Conta as ocorrências por chave enquanto a constrói; qualquer chave com uma contagem acima de uma é duplicada dentro dessa lista Sem segunda passagem, sem estrutura extra.
Na prática o teto é & #39; t a comparação - it& #39; s o navegador renderizando um grupo de resultados com cinquenta mil linhas em uma área de texto A aritmética termina em milissegundos independentemente Se você & #39; re rotineiramente reconciliando listas tão grandes, você provavelmente quer isso em um script em vez de uma guia, e o algoritmo acima é cerca de dez linhas em qualquer idioma.
A classificação vale a pena uma nota Os resultados são classificados naturalmente por padrão, o que significa que numérico-consciente: item2 antes item10ão depois disso Coloca a classificação lexicográfica simples item10 primeiro porque 1 < 2 caractere por caractere, que é correto pela letra da comparação de strings e errado por cada expectativa humana ao digitalizar IDs ou nomes versionados Desligue a classificação e você obterá ordem de inserção - itens na sequência que eles apareceram pela primeira vez em A, depois B - que é ocasionalmente o que você deseja quando a ordem original codifica algo como recência.
Como é isso na prática?
Quatro cenários onde I' realmente usei isso, cada um mapeando para um grupo de resultados diferente.
Limpar uma lista de discussão antes de enviar. Cole a nova lista e a lista enviada anteriormente. Só em A quem tem ' foi contatado - isso' é sua lista de envio. Em ambos quem é & #39; obteria uma duplicata. Duplicatas em A são as quarenta pessoas da história no topo desta página Essa verificação leva quinze segundos e it' s o que teria salvou o engenheiro de suporte uma hora.
Reconciliando dois sistemas. Exporte e-mails de usuários do CRM para A e do faturamento para B. Só em A está inscrito, mas nunca faturado; só em B é faturado-mas-ausente-de-CRM. Estes são dois bugs diferentes O primeiro pode ser um webhook quebrado, o segundo pode ser uma fatura manual alguém levantou fora do fluxo Um único & quot; estas listas diferem & quot; resposta iria obscurecer isso inteiramente, que é exatamente por isso que ambas as direções são relatados separadamente.
Desvio de estoque e catálogo. No mês passado e #39;s Exportação de SKU em relação a este mês e #39;s. Só em A está descontinuado, só em B é novo, em ambos é transportado Classificando assuntos aqui - as exportações saem de diferentes sistemas em diferentes ordens, e um diff relataria todo o arquivo como alterado.
Verificações de sanidade de implantação. Arquivos em staging versus arquivos em produção, de dois ls saídas coladas com o separador de espaço. Só em A é o que tem ' t enviado ainda.
O padrão em todos os quatro: a resposta útil quase nunca é o & quot; as listas são diferentes." It's qual itens, em qual direção - que é precisamente o que as operações de conjunto lhe dão e o que uma pontuação de similaridade ou um resumo diff faz & #39; t.
Minhas listas são enviadas para qualquer lugar?
Não, e pense por um segundo sobre o que você & #39; d colar em uma ferramenta como esta.
It' s uma exportação de assinantes. Uma lista de e-mails de clientes. IDs de funcionários. Chaves de licença. números de conta. As listas que as pessoas reconciliam estão, por natureza, próximas dos dados mais confidenciais que uma organização detém - você não & #39; t reconciliar listas de nada, você reconcilia listas de pessoas. E & quot; deixe-me colar esses dois mil e-mails de clientes em um site aleatório para verificar se há sobreposição e quot; é uma frase que deve impedir você, porque em muitas jurisdições esse & #39; é um relacionamento de processador que você acabou de criar sem contrato.
There' s nenhuma razão para esta computação tocar em uma rede It' s mapas hash sobre strings - algumas centenas de linhas de TypeScript livre de dependência A ferramenta no Toolz.dev é executado inteiramente em sua guia; as listas são strings JavaScript em seu navegador' s memória e eles nunca deixá-lo Nada é carregado, registrado, ou armazenado Verifique-o da maneira que você' d verificar qualquer tal afirmação: abra a guia de rede e clique em Comparar, ou desligue seu wifi e vê-lo continuar funcionando I & #39; escreveu mais sobre por que esta arquitetura importa exatamente para esta classe de dados em Por que as ferramentas baseadas em navegador superam as do lado do servidor.
FAQ
Como faço para comparar duas listas para encontrar o que elas têm em comum?
Cole uma lista na Lista A, a outra na Lista B, e carregue em Comparar. O & quot; Em Both" group é a intersecção - cada item presente em ambas as listas Poderá copiar esse grupo por si só, descarregá - lo como um ficheiro de texto, ou exportar todos os grupos de uma só vez com o Copy Report Order does' t matter, so the lists don' t need to be sorted the same way.
Como faço para encontrar itens que estão em uma lista, mas não na outra?
O & quot; Apenas no A & quot; e o & quot; Apenas no B & quot; os grupos respondem a isso, e eles & #39; são deliberadamente separados Apenas no A os itens que faltam na Lista B; Apenas no B os itens que faltam na Lista A. Estes são geralmente problemas diferentes com causas diferentes - falta de faturamento e falta de CRM são & #39; t o mesmo bug - então colapsá-los em uma resposta perde a informação que você precisa O & quot; Unique & quot; grupo combina ambos se você quiser a diferença simétrica.
Ele pode encontrar duplicatas dentro de uma única lista?
Sim. duplica em A e duplicatas em B lista cada item distinto que aparece mais de uma vez dentro dessa lista Isso é independente da correspondência entre listas, portanto, um item pode ser duplicado em A e presente em B. It' s geralmente a verificação que mais importa na prática, uma vez que duplicatas dentro da lista são o que causa e-mails duplicados e faturamento duplo.
A capitalização afeta a comparação?
Somente se você quiser. A correspondência sensível a maiúsculas e minúsculas está desativada por padrão, portanto [email protected] e [email protected] são tratados como um item - e a saída preserva qualquer forma que você colou em vez de reduzir seus dados. Ligue-o para valores onde o caso carrega significado: caminhos Linux, strings base64, hashes, chaves API, Git SHAs.
Qual é a diferença entre isso e uma ferramenta de diferença de texto?
Um diff é posicional: ele compara a linha 1 com a linha 1 e calcula as edições necessárias para transformar uma sequência na outra, então reordenar uma lista faz com que quase todas as linhas pareçam alteradas Esta ferramenta ignora a ordem inteiramente e só pergunta se um item existe em cada lado Use um diff para código e prosa onde posição é significado; use comparação de lista para reconciliar exportações onde a ordem de classificação é arbitrária.
Posso comparar listas separadas por vírgulas em vez de novas linhas?
Sim - mude o separador para vírgula, ponto e vírgula, espaço ou guia. O espaço em branco ao redor de cada item é cortado por padrão, portanto a, b, c divide-se em três itens limpos Uma ressalva: dividir em vírgulas é & #39; t real CSV análise, por isso, se os seus dados têm campos citados contendo vírgulas, extrair a coluna com uma ferramenta CSV adequada em primeiro lugar.
Quantos itens ele pode suportar?
A comparação indexa cada lista em um mapa hash e é executada em tempo linear em vez de usar loops aninhados, portanto, dezenas de milhares de itens de cada lado são concluídos em milissegundos. O teto prático é o seu navegador renderizando um grupo de resultados muito grande na página, não a comparação em si.
Minhas listas são enviadas para qualquer lugar?
Não. Toda análise e comparação acontece como JavaScript no seu navegador - nada é transmitido, registrado ou armazenado Isso importa aqui mais do que para a maioria das ferramentas, porque as listas que as pessoas reconciliam geralmente são e-mails de clientes, IDs de funcionários ou chaves de licença Assista sua guia de rede enquanto compara, ou fique offline e ela continue funcionando.
Ferramentas relacionadas: Verificador de diff de texto Quando a ordem e a posição são importantes, json diff Para dados estruturados, Visualizador de CSV Para extrair uma coluna de um CSV real e contador de palavras Para contagens rápidas. Leitura adicional: Por que as ferramentas baseadas em navegador superam as do lado do servidor e O kit de ferramentas do desenvolvedor web.



