比較兩個清單並找出差異,代表要從兩個輸入讀取五個標記清楚的輸出——同時出現在兩個清單中的項目、只出現在 A 的項目、只出現在 B 的項目、聯集,以及對稱差集——其中每個非空白的修剪後行都視為恰好一個集合成員。「Compare Two Lists」會嚴格套用這條規則:空行會被捨棄,CRLF 與單獨的 CR 行尾會轉為 LF,每行周圍的空白會被修剪,而每個重複的鍵會保留第一次出現時的拼寫。同一組經過標準化的陣列會同時供應可見的面板與複製的報表,且處理過程都在你的瀏覽器本機進行,因此不會上傳、記錄或傳送至任何比較服務。如果你的目標是回答「哪些項目同時出現在兩個清單中」、「哪些是各自獨有的」,以及「合併後的集合長什麼樣」,那麼一個以行為基礎的集合工具就能讓你一次取得所有答案。

compare two lists and find differences
compare two lists and find differences

你應該預期的五種集合檢視

成員比較不是一個數字,而是一小群標準的集合運算。這些標籤沿用了 JavaScript 與 Python 集合各自文件中記載的相同含義,因此你在報表中看到的詞彙並非專屬術語。Compare Two Lists 會在一次處理中計算全部五種,並各自顯示在標記清楚的段落中,讓你能透過單次貼上與複製的動作,回答好幾個成員相關的問題。

SectionAlso calledWhat it contains
In bothIntersectionMembers present in List A and List B
Only in AA minus B, directional differenceMembers present in List A but absent from List B
Only in BB minus A, directional differenceMembers present in List B but absent from List A
UnionEither or bothAll members from List A followed by any new members from List B
Either not bothSymmetric differenceMembers present in exactly one of the two lists

每個段落內部的順序依循在 List A 中首次出現的順序,再依序加入任何新的 List B 成員(若適用)。這個工具不會對結果進行排序,因此如果你需要依字母順序排列的輸出,可以在不更改成員的前提下,把標記清楚的報表另外丟給一個排序工具處理。

三步驟執行比較

這個工作流程刻意設計得很短。以行為基礎的集合工具重點在於讓你把注意力放在清單本身,而不是設定面板。

  1. 把每個項目一行貼進 List A 與 List B。每個非空白的修剪後行會成為一個集合成員。空行會被捨棄,CRLF 與單獨的 CR 行尾會標準化為 LF,而重複的鍵會保留第一次顯示的拼寫,不會產生多個列。
  2. 選擇字母大小寫是否影響成員判定。預設為不區分大小寫,這符合最常見的預期:Apple 和 apple 應視為同一列。當你的下游系統會區分大小寫時(例如比較產品代碼或區分大小寫的識別碼),請切換為區分大小寫。
  3. 進行比較、檢視每個標記清楚的段落,並複製報表。閱讀 In both、Only in A、Only in B、Union,以及 Either not both。「複製所有結果」會以固定順序產生五個大寫標題,並以 LF 分隔各值,而空段落會以破折號表示,讓「不存在」這件事保持可見。在貼到其他地方之前請先確認剪貼簿已成功寫入,並核對字面行政策是否符合將接收結果的目的端系統。

如果任一清單超過一百萬個 UTF-16 碼元或 50,000 行,或是兩個標準化後的清單皆為空,工具會回傳明確的錯誤,而非部分結果。這些上限能讓分割、對應、渲染與剪貼簿輸出在各種瀏覽器與輸入大小下都保持可預測。

大小寫敏感度與首次拼寫的穩定性

兩個看起來幾乎相同的清單成員,是「為什麼這個不見了」這類困惑最常見的來源。規則簡單明瞭,值得直接說清楚:在不區分大小寫的模式下,Apple 和 apple 共用同一個成員鍵,而你在報表中看到的會是你先輸入的那個拼寫。在區分大小寫的模式下,它們會被視為兩個不同的成員,並各自依其成員規則出現在對應位置。所選的政策會一致地套用於去重與全部五種運算,因此要切換這兩種解讀方式,只需要切換開關即可。

大小寫不敏感模式的實際範例。假設 List A 包含 apple、banana、pear,而 List B 包含 banana、peach。

  • 兩個清單共用的成員鍵:banana。這就是 In both 段落的全部內容。
  • 存在於 A 但不存在於 B 的鍵:apple 與 pear。Only in A 顯示為 apple、pear。
  • 存在於 B 但不存在於 A 的鍵:peach。Only in B 顯示為 peach。
  • Union 會先走訪 A,再附加任何新的 B 鍵:apple、banana、pear、peach。
  • 對稱差集為 A 獨有加上 B 獨有:apple、pear、peach。

把同一組清單切換到區分大小寫模式,運算結果仍然成立;改變的是不同成員鍵的集合。若 List A 以 Apple(大寫 A)作為首次出現,而 List B 則是 apple,則在不區分大小寫的報表中,common 與 union 段落會顯示 Apple;而在區分大小寫模式下,這兩行會被視為不同的成員,各自僅出現在自己的 A-only 或 B-only 段落。在把結果視為權威之前,請先檢視政策,特別是當下游系統擁有與你貼上的內容不一致的標準化規則時。

這個工具不會做的事

成員比較有其明確的界線,假裝沒有界線只會讓人失望。這個工具不是資料庫 join、試算表合併器、差異檢視器、模糊去重器、安全存取控制驗證器,或對帳服務。它不會解析 CSV、不會切分逗號、不會標準化 Unicode、不會移除標點符號、不會以數值方式比較數字、不會解析 URL,也不會執行模糊比對。在所選的大小寫規則下,一個實體行就是一個字面項目,行內空白會在周圍空白被修剪後保留下來。

它無法辨識別名、等價網域、Unicode 易混淆字元、數值範圍或商業身分。若兩行在標準化後並非完全相同,就會被視為不同成員,且不會被合併。編輯任一文字區域會清除先前的結果,因此請先複製報表,再開始重新編輯任一輸入。

以行為基礎比較的實際情境

一旦你能從兩份貼上的清單取得五個標記清楚的輸出,許多日常清理工作就能化為單次比較,而不再需要試算表公式。

  • 電子郵件名單。找出只出現在 List A 而未出現在 List B 的訂閱者,或建立一份聯集,以避免在平台遷移期間重複寄送同一份電子報。
  • 庫存識別碼。不必打開試算表,就能找出倉庫匯出中有、店面目錄中沒有的 SKU,反之亦然。
  • 關鍵字與標籤集合。稽核舊活動中出現、但新活動中沒有的關鍵字,或比較兩組標籤集合,找出編輯流程之間是否意外產生漂移。
  • 出席者與允許名單。把賓客名單與報名匯出進行對帳,或檢查新的允許名單是否涵蓋先前名單上的所有項目。
  • 檔名與 URL 集合。找出兩份快照之間被重新命名或刪除的檔案,或確認重新導向對應表是否涵蓋所有舊的 URL。

在信任輸出前先加以驗證

比較報表的價值,取決於你比較的政策以及你要餵入的目的端。較新的 JavaScript Set 方法與 Python 內建的 set 型別,都以標準術語記載了相同的五種運算,當輸出讓你感到意外時,這是個很好的檢查依據。請確認在期望 Apple 與 apple 合併時,「區分大小寫」模式確實為關閉;反之,在期望它們分開時也請確認模式為開啟。請留意標示空段落的破折號,以免一個靜默為空的結果假裝成有內容。請將首次出現的拼寫視為標準答案:若在 List A 中 Apple 先出現,而 List B 中 apple 先出現,在不區分大小寫的比較下,common 與 union 段落會一致顯示 Apple,而非 apple。

最後,請記住處理模型。同一組經過標準化的陣列會同時供應可見的面板與複製的報表,且剪貼簿寫入成功的訊息只會在瀏覽器確認寫入後才會回報。若剪貼簿權限被拒絕,工具會回傳手動複製的指示,而非假裝成功,因此你隨時都能知道報表是否確實進入了系統剪貼簿。若有疑慮,請把複製的報表貼回一個全新的文字區域,確認字面行是否在來回傳輸中倖存,特別是當目的端系統會套用自身的行尾標準化時。

延伸閱讀:Compare Two Lists for Differences: Five Views at Once

延伸閱讀:How to Randomize a List Fairly