訂明本例驗收任務
假設表格同一欄有多段文字,各段有文字字串及已標是否劃掉。明示空字串是已觀察空白,欠文字或不是文字則無效。本例把劃掉的列歷史值,未劃掉須恰好一段才定現值;沒有或多於一段便待覆核。刪改標記由觀察提供,驗算不辨識手寫。
- 分開已劃掉及未劃掉文字
- 數現值候選
- 恰好一個才接受,否則保留覆核
現值多於一個或沒有,覆核原欄。
使用已填個案
| 個案 | 已提供輸入 | 預期結構化結果 | 判斷及原因 |
|---|---|---|---|
| 一個可見替換值 | {"spans":[{"text":"12","struck":true},{"text":"14","struck":false}]} | {"old":["12"],"current":"14","candidates":["14"],"status":"accepted"} | 十四為現值,十二仍保留為原刪文字。 |
| 兩個未劃掉候選 | {"spans":[{"text":"14","struck":false},{"text":"16","struck":false}]} | {"old":[],"current":null,"candidates":["14","16"],"status":"review"} | 本規則沒有最後一段或最近位置優先。 |
| 刪改標籤是文字 | {"spans":[{"text":"14","struck":"false"}]} | {"error":"observation-label"} | 文字 false 不是布林觀察,不能當清楚標記。 |
| 欠觀察文字 | {"spans":[{"struck":false}]} | {"error":"observation-text"} | 未劃掉標籤清楚,也不能補欠缺現值文字。 |
| 明示已觀察空白 | {"spans":[{"text":"","struck":false}]} | {"old":[],"current":"","candidates":[""],"status":"accepted"} | 空字串是已觀察空白值,不是欠文字欄。 |
| 全部值都被劃掉 | {"spans":[{"text":"12","struck":true}]} | {"old":["12"],"current":null,"candidates":[],"status":"review"} | 看到舊值也不能補作現值。 |
逐步處理 all-struck 個案,須得到甚麼結果?原因是甚麼?
查看參考答案
{"old":["12"],"current":null,"candidates":[],"status":"review"}。看到舊值也不能補作現值。
執行完整本機驗算
import assert from 'node:assert/strict';
function evaluate(x){
if(x.spans.some(s=>typeof s.text!=='string'))return {error:'observation-text'};
if(x.spans.some(s=>typeof s.struck!=='boolean'))return {error:'observation-label'};
const old=x.spans.filter(s=>s.struck).map(s=>s.text),current=x.spans.filter(s=>!s.struck).map(s=>s.text);
return {old,current:current.length===1?current[0]:null,candidates:current,status:current.length===1?'accepted':'review'};
}
const cases = [
{
"id": "one-replacement",
"input": {
"spans": [
{
"text": "12",
"struck": true
},
{
"text": "14",
"struck": false
}
]
},
"expected": {
"old": [
"12"
],
"current": "14",
"candidates": [
"14"
],
"status": "accepted"
}
},
{
"id": "two-current-spans",
"input": {
"spans": [
{
"text": "14",
"struck": false
},
{
"text": "16",
"struck": false
}
]
},
"expected": {
"old": [],
"current": null,
"candidates": [
"14",
"16"
],
"status": "review"
}
},
{
"id": "string-strike-label",
"input": {
"spans": [
{
"text": "14",
"struck": "false"
}
]
},
"expected": {
"error": "observation-label"
}
},
{
"id": "span-text-absent",
"input": {
"spans": [
{
"struck": false
}
]
},
"expected": {
"error": "observation-text"
}
},
{
"id": "explicit-blank-transcription",
"input": {
"spans": [
{
"text": "",
"struck": false
}
]
},
"expected": {
"old": [],
"current": "",
"candidates": [
""
],
"status": "accepted"
}
},
{
"id": "all-struck",
"input": {
"spans": [
{
"text": "12",
"struck": true
}
]
},
"expected": {
"old": [
"12"
],
"current": null,
"candidates": [],
"status": "review"
}
}
];
for (const c of cases) assert.deepEqual(evaluate(c.input), c.expected, c.id);
console.log(JSON.stringify({checked:cases.length,caseIds:cases.map(c=>c.id)}));
舊值與現值分開保留。換文件時要另提供刪改規則;劃線本身不是通用授權。