Un ingegnere di supporto una volta mi chiese perché quaranta clienti avevano ricevuto due volte una mail di rinnovo, la risposta richiedeva un'ora per essere trovata ed era completamente banale: la lista della campagna era stata assemblata incollando un'esportazione sotto un'altra, ed esistevano quaranta indirizzi in entrambi Nessuno aveva controllato, perché controllare significava o far occhialare duemila righe o scrivere un VLOOKUP quella metà della squadra lo fece e #39; t fidati. Quindi nessuno ha controllato, e alle stesse quaranta persone è stato detto due volte che la loro carta stava per essere addebitata.
Questa è la forma di questo problema. Riconciliare due elenchi è una delle cose più comuni che chiunque fa con i dati, e it' è abbastanza noioso da far sì che le persone lo saltino o lo facciano male. L'istinto è solitamente quello di raggiungere uno strumento diff, incollare entrambi gli elenchi e strizzare gli occhi all'output colorato - che fallisce immediatamente, perché un diff risponde a una domanda che hai fatto' t chiedere. Oppure vai su un foglio di calcolo e inizi a montare MATCH/COUNTIF formule, che funziona ma richiede dieci minuti e produce un artefatto you' non riutilizzerò mai.
L'operazione che desideri effettivamente ha un nome e it' è più vecchia di qualsiasi strumento: imposta aritmetica. Intersezione, differenza, unione. Costruisco [Toolz.dev](/e metto un browser-based strumento di confronto elenchi lì, ma questa guida riguarda i concetti sottostanti: perché l'ordine dovrebbe essere ignorato, quale caso si rompe silenziosamente e come scegliere tra questo e un differenziale.
tl; dr: Per confrontare due elenchi, tratta ciascuno come un insieme non ordinato e calcola l'intersezione (elementi in entrambi), le due differenze (elementi solo in A, elementi solo in B) e i duplicati all'interno di ciascun elenco Ignora completamente l'ordine: una differenza di riga è lo strumento sbagliato perché it' è posizionale, quindi riordinare un elenco fa sì che quasi tutte le righe sembrino modificate Piega la custodia per identificatori come le e-mail ma conserva il testo originale nell'output, taglia gli spazi bianchi prima di confrontarli e fallo nel browser poiché gli elenchi che le persone riconciliano sono solitamente dati del cliente.
A quali domande risponde effettivamente il confronto tra due elenchi?
Una volta viste le operazioni nominate, le forme diventano ovvie Data lista A e lista B:
- Intersezione- cosa's in entrambi? quali abbonati sono anche clienti paganti Quale del mese scorso's SKUs sono ancora in questo mese's catalogo.
- A meno B- what's solo in A? quali utenti nel CRM non hanno mai fatto fatturare Quali file esistono localmente ma non sul server.
- B meno A- cosa' è solo in B? La stessa domanda nella direzione opposta, e it's un differente domanda. Mancanti-da-fatturazione e mancanti-da-CRM sono due bug distinti con due cause distinte.
- Differenza simmetrica- what's in esattamente un elenco? l'unione di entrambe le differenze: tutto ciò che non è riuscito a corrispondere, indipendentemente dalla direzione Questo è il & quot; what's fuori sincronia?" domanda.
- Unione- tutto da entrambi gli elenchi, deduplicato L'unione, eseguita correttamente.
- Duplica all'interno di un elenco- cosa' si ripete solo dentro A? Questo è't un paragone, ma è sempre la domanda di cui ti risulta aver bisogno, perché è's cosa causa il doppio invio e la doppia fatturazione.
Vale la pena separare quest'ultimo. La corrispondenza tra elenchi e la duplicazione all'interno dell'elenco sono indipendenti: un indirizzo può apparire due volte in A e appare anche in B. Gli strumenti che riportano solo i risultati tra elenchi non colgono il fallimento che costa denaro.
Tutto qui si mappa direttamente sulle operazioni che già conosci da SQL - INTERSECT, EXCEPT, UNION- e sulle formule dei fogli di calcolo. Il valore di uno strumento dedicato è't che fa qualcosa che puoi't; it's che tutte e sei le risposte vengono visualizzate da una pasta, invece di sei formule diverse.
Perché uno strumento diff è la scelta sbagliata per confrontare gli elenchi?
Questo è l'errore che vedo di più, e vale la pena essere preciso su & quot; confronta due elenchi& quot; e & quot;diff due file" suonano come sinonimi.
Un diff è posizionale. Gli algoritmi diff calcolano lo script di modifica minimo: la sequenza più breve di inserzioni ed eliminazioni che trasforma una sequenza nell'altra. That' è il modello giusto per il codice sorgente e la prosa, dove si trova la riga 40 che segue la riga 39 significativo. Spostare una funzione e un diff riporta correttamente che hai spostato una funzione.
Un elenco non ha un ordine significativo. La riga 300 nell'esportazione CRM non ha alcuna relazione con la riga 300 nell'esportazione di fatturazione. Loro' sono due sacchetti di articoli che vengono scritti in qualunque sequenza il database sia stato restituito.
Dai dati non ordinati a un algoritmo posizionale e ottieni rumore Prendi due elenchi con contenuti identici, ordina uno di essi e diffonili:
List A List B
alice bob
bob alice
carol carol
Un diff riporta che alice è stato rimosso e aggiunto nuovamente, o quello bob mosso - alcuni churn proporzionale a come diversamente i due sono ordinati La risposta corretta è non è cambiato niente. Ogni elemento è in entrambi gli elenchi. Gli insiemi sono uguali. Una differenza può e n. 39; t dirlo perché è & n. 39; t chiedere informazioni sull'appartenenza.
La tabella comparativa, poiché gli strumenti si sovrappongono realmente nella mente delle persone che li cercano entrambi:
| Elenco Confronta | testo Differenza | |
|---|---|---|
| Modello | Insieme non ordinato di elementi | Sequenza ordinata di linee |
| L'ordine conta? | No - riordina liberamente, risultati identici | Sì - riordinare gli spettacoli come modifiche |
| Risposte | Appartenenza: in entrambi, solo A, solo B, duplicato | Modifiche: cosa inserire/eliminare per trasformare A in B |
| Articoli duplicati | Segnalato esplicitamente come gruppo | Solo altre righe |
| bene per | Riconciliazione esportazioni, liste e-mail, ID, SKU, inventari | Codice sorgente, prosa, file di configurazione, qualsiasi cosa in cui la posizione è significato |
| Male per | Confronto di due versioni di un documento | Qualsiasi elenco in cui l'ordine di ordinamento è arbitrario |
La regola: se tu'd essere ugualmente soddisfatto dell'elenco ordinato in modo diverso, vuoi un confronto prestabilito. Se riordinare le linee sarebbe un vero cambiamento che vale la pena segnalare, si desidera che il Controllore del differenziale di testo. Per i dati strutturati con nesting anziché linee piatte, nessuno dei due si applica: quello's cosa il JSON DIFF è per, poiché si confronta per percorso chiave piuttosto che per linea o per appartenenza.
Come dovrebbe funzionare la sensibilità del caso?
Questa è l'opzione che le persone lasciano per impostazione predefinita e poi sbagliano silenziosamente, quindi vale la pena riflettere una volta.
La corrispondenza senza distinzione tra maiuscole e minuscole è l'impostazione predefinita giusta per i dati che la maggior parte delle persone confronta Indirizzi e-mail, nomi utente, nomi di dominio, codici prodotto, codici paese: questi sono convenzionalmente insensibili alla pratica e [email protected] e [email protected] sono la stessa persona in ogni sistema che conta.
There's un avvertimento pedante qui che's vale la pena sapere perché it's occasionalmente portanti: per RFC5321, la parte di dominio di un indirizzo email non fa distinzione tra maiuscole e minuscole, ma il locale parte - tutto prima del @- è formalmente case-sensitive e lasciato al server di posta ricevente per interpretare Così [email protected] e [email protected] in linea di principio potrebbero essere caselle di posta diverse In pratica essenzialmente ogni fornitore principale le tratta come identiche, e se tu're deduplicare una mailing list dovresti assolutamente piegare il caso Ma se tu're debug perché rimbalza un indirizzo specifico, quello's il tipo di dettaglio che risulta essere importante.
Caso-sensibile la corrispondenza è corretta per qualsiasi cosa in cui il caso trasporta informazioni: percorsi di file Linux, stringhe base64, hash, token JWT, chiavi API, Git SHA, la maggior parte degli identificatori di programmazione Il caso pieghevole su un elenco di hash di password unirebbe valori distinti e ti darebbe una risposta sicuramente sbagliata.
Il dettaglio di implementazione che conta più dell'opzione stessa: piegare il caso per la corrispondenza, ma mostrare il testo originale. Se incolli [email protected] e lo strumento ti dice & #39; in entrambi gli elenchi, dovrebbe tornare indietro [email protected]- no [email protected]. L'abbassamento dell'output corrompe silenziosamente i tuoi dati durante il passaggio e, poiché il solito passaggio successivo è incollare il risultato da qualche altra parte, la corruzione viaggia. Lo strumento mantiene la forma vista per la prima volta di ogni elemento e corrisponde a una chiave piegata dietro le quinte, quindi quello che esce è quello che inserisci.
Whitespace merita lo stesso trattamento e si pensa meno Copia una colonna da un foglio di calcolo o dividi una riga come a, b, c sulle virgole e ottieni oggetti che trasportano spazi principali. [email protected] e [email protected] sono stringhe diverse e indirizzi identici Il taglio è attivo per impostazione predefinita per questo motivo e it' è l'opzione you'd avviso mancante entro circa trenta secondi dall'uso reale.
Quale separatore devo usare?
L'impostazione predefinita è un elemento per riga, ovvero ciò che ottieni incollando una colonna di foglio di calcolo: gli appunti distribuiscono valori separati da una nuova riga, quindi una colonna di e-mail da Excel, Fogli Google o un'esportazione CSV viene visualizzata senza riformattazione.
Gli altri separatori coprono dati che arrivano già in linea Comma per una singola riga CSV o un array copiato Semicolon per la convenzione Outlook e old-Windows per gli elenchi di indirizzi Spazio per l'output della shell - ls, git diff --name-only convogliato attraverso tr, qualsiasi cosa delimitata dallo spazio Scheda per una riga incollata da un foglio di calcolo orizzontalmente anziché verticalmente.
Una cosa da notare: dividere sulle virgole è no analisi CSV Un vero campo CSV può contenere una virgola all'interno delle virgolette e una divisione ingenua si strapperà "Smith, Jane" in due elementi. Se tu' stai estraendo una colonna da un file CSV autentico con campi citati, eseguila attraverso il file Visualizzatore CSV in primo luogo - si implementa il RFC 4180 vero e proprio quoting regole - poi copiare la colonna che si desidera Per un elenco piatto di e-mail o ID senza virgole incorporate, la suddivisione va bene e questo non fa' t venire su.
Le voci vuote vengono eliminate per impostazione predefinita, perché sono quasi sempre artefatti: una nuova riga finale alla fine di un incolla, una riga vuota in un foglio di calcolo, una doppia virgola Una stringa vuota è & #39; t un elemento in qualsiasi elenco a cui tieni veramente L'opzione esiste se tu & #39; stai cercando specificamente righe vuote in un'esportazione, che è una cosa reale anche se insolita da desiderare.
Come fa la scala di confronto?
L'approccio ingenuo per confrontare due elenchi è un ciclo annidato: per ogni elemento in A, scansiona tutto B. That's O (n×m) e it' va bene per cento elementi e inutilizzabile per cinquantamila, dove tu' stai facendo 2,5 miliardi di confronti di stringhe.
L'approccio giusto indicizza ogni elenco in una mappa hash codificata dalla chiave di confronto - la forma piegata e ritagliata dell'elemento - con il valore che è l'originale visto per la prima volta Costruire ogni indice è un passaggio lineare Quindi ogni domanda diventa una ricerca a tempo costante per elemento: questa chiave è in B & #39; s map? L'intero confronto è O (n+m), il che significa che ventimila elementi su ciascun lato sono quarantamila operazioni hash e si completa più velocemente di quanto il browser possa ridipingere.
Lo stesso indice dà gratuitamente i duplicati Conta le occorrenze per chiave mentre la costruisci; qualsiasi chiave con un conteggio superiore a uno viene duplicata all'interno di quell'elenco Nessun secondo passaggio, nessuna struttura extra.
In pratica il soffitto è & #39; t il confronto - it' s il browser che rende un gruppo di risultati con cinquantamila righe in un'area di testo L'aritmetica termina in millisecondi a prescindere Se tu & #39; stai riconciliando abitualmente elenchi così grandi, probabilmente lo vuoi in uno script piuttosto che in una scheda, e l'algoritmo sopra è di circa dieci righe in qualsiasi lingua.
L'ordinamento vale una nota I risultati sono ordinati naturalmente per impostazione predefinita, ovvero numerico-consapevole: item2 prima item10non dopo. Lo smistamento lessicografico semplice mette item10 prima perché 1 < 2 carattere per carattere, che è corretto dalla lettera di confronto delle stringhe e sbagliato da ogni aspettativa umana durante la scansione di ID o nomi con versione Disattiva l'ordinamento e ottieni l'ordine di inserimento - elementi nella sequenza in cui sono apparsi prima in A, poi in B - che è occasionalmente ciò che desideri quando l'ordine originale codifica qualcosa come la recenza.
Come si presenta in pratica?
Quattro scenari in cui I' l'ho effettivamente utilizzato, ciascuno mappando su un gruppo di risultati diverso.
Pulizia di una mailing list prima di un invio. Incolla il nuovo elenco e l'elenco inviato in precedenza. Solo in A è chi ha't è stato contattato - that's la tua lista di invio. In entrambi è chi'd ottenere un duplicato. Duplicati in A ci sono le quaranta persone della storia nella parte superiore di questa pagina. Quel controllo richiede quindici secondi e it' è quello che avrebbe fatto risparmiare un'ora all'ingegnere del supporto.
Conciliare due sistemi. Esporta le email degli utenti dal CRM in A e dalla fatturazione in B. Solo in A è registrato ma non viene mai fatturato; solo in B è fatturato-ma-mancante-da-CRM. Questi sono due bug diversi Il primo potrebbe essere un webhook rotto, il secondo potrebbe essere una fattura manuale qualcuno sollevato al di fuori del flusso Un singolo & quot; questi elenchi differiscono" risposta sarebbe oscurare che interamente, che è esattamente il motivo per cui entrambe le direzioni sono riportate separatamente.
Deriva inventario e catalogo. Il mese scorso's SKU esportazione contro questo mese's. Solo in A è interrotto, solo in B è nuovo, in entrambi viene riportato. Ordinamento qui: le esportazioni provengono da sistemi diversi in ordini diversi e un diff riporterebbe l'intero file come modificato.
Controlli di sanità mentale della distribuzione. File sulla messa in scena rispetto ai file sulla produzione, da due ls uscite incollate con il separatore di spazio. Solo in A è ciò che ha ancora & #39;t spedito.
Lo schema tra tutti e quattro: la risposta utile non è quasi mai & quot; gli elenchi sono diversi.& quot; It's cui articoli, in cui direzione - che è esattamente ciò che ti danno le operazioni impostate e cosa fa un punteggio di somiglianza o un riepilogo della differenza't.
Le mie liste vengono caricate da qualche parte?
No, e pensa per un secondo a cosa tu'd incolla in uno strumento come questo.
It's un'esportazione di abbonati Un elenco di e-mail dei clienti ID dei dipendenti Chiavi di licenza Numeri di conto Gli elenchi che le persone riconciliano sono, per loro natura, vicini ai dati più sensibili che un'organizzazione detiene: non riconcili elenchi di nulla, riconcili elenchi di persone. E & quot; lasciami semplicemente incollare queste duemila e-mail dei clienti in un sito Web casuale per verificare sovrapposizioni e quot; è una frase che dovrebbe fermarti, perché in molte giurisdizioni ' è una relazione con il processore che hai appena creato senza contratto.
There's nessun motivo per questo calcolo di toccare una rete It's hash maps su stringhe - alcune centinaia di righe di TypeScript senza dipendenze Lo strumento su Toolz.dev viene eseguito interamente nella scheda; gli elenchi sono stringhe JavaScript nel browser's memoria e non lo lasciano mai Nulla viene caricato, registrato o archiviato Verificalo nel modo in cui tu'd verificare qualsiasi affermazione del genere: aprire la scheda di rete e premere Confronta, o disattivare il wifi e guardarlo continuare a funzionare I've scritto di più sul motivo per cui questa architettura è importante esattamente per questa classe di dati in Perché gli strumenti basati su browser battono quelli lato server.
FAQ
Come faccio a confrontare due elenchi per trovare ciò che hanno in comune?
Incolla un elenco nell'elenco A, l'altro nell'elenco B e premi Confronta. Il gruppo & quot;In Both" è l'intersezione: ogni elemento presente in entrambi gli elenchi Puoi copiare quel gruppo da solo, scaricarlo come file di testo o esportare ogni gruppo contemporaneamente con Copy Report. L'ordine non ha e n. 39; non importa, quindi gli elenchi non sono e n. 39; non devono essere ordinati allo stesso modo.
Come trovo gli elementi che sono in una lista ma non nell'altra?
Il & quot; Solo in A" e & quot; Solo in B" i gruppi rispondono e loro' sono deliberatamente separati Solo in A contiene elementi mancanti dall'Elenco B; Solo in B contiene elementi mancanti dall'Elenco A. Questi sono solitamente problemi diversi con cause diverse: mancante nella fatturazione e mancante nel CRM aren' t lo stesso bug - quindi comprimerli in un'unica risposta perde le informazioni di cui hai bisogno Il gruppo & quot; Unique" combina entrambi se vuoi la differenza simmetrica.
Può trovare duplicati all'interno di un singolo elenco?
Sì. i duplicati in A e i duplicati in B elencano ogni elemento distinto che appare più di una volta all'interno di tale elenco. Questo è indipendente dalla corrispondenza tra elenchi, quindi un elemento può essere sia duplicato in A che presente in B. It' di solito è il controllo che conta di più nella pratica, poiché i duplicati all'interno dell'elenco sono ciò che causa e-mail duplicate e doppia fatturazione.
La capitalizzazione influisce sul confronto?
Solo se lo desideri La corrispondenza sensibile al caso è disattivata per impostazione predefinita, quindi [email protected] e [email protected] sono trattati come un elemento - e l'output preserva qualunque forma hai incollato piuttosto che abbassare i tuoi dati Attivalo per i valori in cui il caso porta significato: percorsi Linux, stringhe base64, hash, chiavi API, Git SHA.
Cosa' è la differenza tra questo e uno strumento di diff testuale?
Un diff è posizionale: confronta la riga 1 con la riga 1 e calcola le modifiche necessarie per trasformare una sequenza nell'altra, quindi riordinare un elenco fa sì che quasi ogni aspetto della riga venga modificato Questo strumento ignora completamente l'ordine e chiede solo se esiste un elemento su ciascun lato Usa un diff per codice e prosa dove la posizione è significato; usa il confronto degli elenchi per riconciliare le esportazioni dove l'ordine di ordinamento è arbitrario.
Posso confrontare le liste separate da virgole anziché da nuove righe?
Sì - passa il separatore a virgola, punto e virgola, spazio o scheda Lo spazio bianco attorno a ciascun elemento viene tagliato per impostazione predefinita, quindi a, b, c si divide in tre elementi puliti Un avvertimento: dividere sulle virgole è' t analisi CSV reale, quindi se i tuoi dati hanno citato campi contenenti virgole, estrai prima la colonna con uno strumento CSV adeguato.
Quanti oggetti può gestire?
Il confronto indicizza ogni elenco in una mappa hash e viene eseguito in tempo lineare anziché utilizzare cicli nidificati, quindi decine di migliaia di elementi su ciascun lato vengono completati in millisecondi Il tetto pratico è il tuo browser che esegue un gruppo di risultati molto ampio nella pagina, non il confronto stesso.
Le mie liste vengono caricate da qualche parte?
No. Tutto l'analisi e il confronto avvengono come JavaScript nel tuo browser - nulla viene trasmesso, registrato o archiviato Questo conta qui più che per la maggior parte degli strumenti, perché gli elenchi che le persone riconciliano sono solitamente e-mail dei clienti, ID dei dipendenti o chiavi di licenza Guarda la scheda di rete durante il confronto, o vai offline e continua a funzionare.
Strumenti correlati: Controllore del differenziale di testo Quando l'ordine e la posizione contano, JSON DIFF per dati strutturati, Visualizzatore CSV per estrarre una colonna da un CSV reale, e Contatore di parole per conteggi rapidi. Ulteriori letture: Perché gli strumenti basati su browser battono quelli lato server e Il toolkit dello sviluppatore web.



