先核來源與已訂規則
本例要查 NFC 等價字樣,但每個原標籤都須留。單字 é 與 e 加組合重音有同一 NFC 鍵;一鍵內有不同原寫法便暫停,相同寫法重複則照留,不當作此類碰撞。
| 紀錄 | 輸入 JSON |
|---|---|
| 原例輸入 | {"labels":["é","é"]} |
比較兩條實際路徑
更正留下兩原字樣並指出 é 鍵,不覆寫寫法,也不因此認定兩筆業務紀錄是同一對象。
| 路徑 | 輸出 JSON |
|---|---|
| 錯誤路徑 | {"accepted":true,"labels":["é"]} |
| 更正路徑 | {"accepted":false,"originals":["é","é"],"collisions":[{"key":"é","originals":["é","é"]}]} |
import {DatabaseSync} from 'node:sqlite';
import {TextDecoder} from 'node:util';
import {inflateSync} from 'node:zlib';
import {posix} from 'node:path';
import {createHash} from 'node:crypto';
const rows=(db,sql)=>db.prepare(sql).all().map(r=>({...r}));
const failed=(action)=>{try{action();return null;}catch(e){return {code:e.errcode??e.code??e.name};}};
import assert from 'node:assert/strict';
const run=function run(i,corrected=true){
const groups=new Map();for(const source of i.labels){const key=source.normalize('NFC');if(!groups.has(key))groups.set(key,[]);groups.get(key).push(source);}
if(!corrected)return {accepted:true,labels:[...groups.keys()]};
const collisions=[...groups].filter(([,originals])=>new Set(originals).size>1).map(([key,originals])=>({key,originals}));
return {accepted:collisions.length===0,originals:[...i.labels],collisions};
};
const cases=[{"label":"misleading base","input":{"labels":["é","é"]},"expected":{"accepted":true,"labels":["é"]},"corrected":false},{"label":"corrected base","input":{"labels":["é","é"]},"expected":{"accepted":false,"originals":["é","é"],"collisions":[{"key":"é","originals":["é","é"]}]},"corrected":true},{"label":"repeated identical spelling","input":{"labels":["é","é"]},"expected":{"accepted":true,"originals":["é","é"],"collisions":[]},"corrected":true},{"label":"two distinct normal forms","input":{"labels":["A","B"]},"expected":{"accepted":true,"originals":["A","B"],"collisions":[]},"corrected":true}];
for(const test of cases){
const actual=run(test.input,test.corrected);
assert.deepEqual(actual,test.expected,test.label);
console.log(test.label,actual);
}
下次載入前核邊界
兩個完全相同 é 仍留兩項,沒有不同寫法碰撞;A、B 各有自己的鍵。
| 情況 | 輸入 JSON | 預期輸出 JSON |
|---|---|---|
| 完全相同字樣重複 | {"labels":["é","é"]} | {"accepted":true,"originals":["é","é"],"collisions":[]} |
| 正規鍵各自不同 | {"labels":["A","B"]} | {"accepted":true,"originals":["A","B"],"collisions":[]} |
兩種來源寫法應否改存一個 é?
查看參考答案
不應。本例是比較後暫停,兩原值保留;NFC 鍵是核對資料,不是替代紀錄。