來源格式與預期記錄
這是原創假設轉換例子。輸入限下列欄位的普通、無循環 JSON 形記錄,統一記錄格式及拒絕代碼由本例訂明。若換來源,先修改格式約定。
本例橫欄以不重複、非空貨品標籤作欄頭,每行須按欄頭次序填齊非負安全整數數量。每格各產生一項,記下來源行、組別及貨品,零數量也保留。任何一行欄數不符,整次轉換拒絕。
| 個案 | 輸入記錄(JSON) | 預期輸出(JSON) |
|---|---|---|
| 矩陣轉明細 | {"items":["A","B"],"rows":[{"group":"North","units":[2,0]}]} | {"ok":true,"value":{"lines":[{"sourceRow":1,"group":"North","item":"A","units":2},{"sourceRow":1,"group":"North","item":"B","units":0}]}} |
| 拒絕欄數不足 | {"items":["A","B"],"rows":[{"group":"North","units":[2]}]} | {"ok":false,"error":"GRID_WIDTH"} |
| 保留空矩陣 | {"items":["A"],"rows":[]} | {"ok":true,"value":{"lines":[]}} |
在本機執行轉換
把完整例子以 JavaScript 模組在 Node.js 執行,內含純轉換函數、三個輸入及寫明的預期輸出,對不上便由斷言停止。拒絕個案回傳 ok=false 及代碼,不回傳半份統一記錄。
import assert from 'node:assert/strict';
function orderGrid(i){
const fail=error=>({ok:false,error});
if(!i||!Array.isArray(i.items)||!Array.isArray(i.rows)||i.items.some(x=>typeof x!=='string'||!x)||new Set(i.items).size!==i.items.length)return fail('GRID_HEADER');
const lines=[];
for(let row=0;row<i.rows.length;row++){
const r=i.rows[row];if(!r||typeof r.group!=='string'||!Array.isArray(r.units)||r.units.length!==i.items.length)return fail('GRID_WIDTH');
if(r.units.some(n=>!Number.isSafeInteger(n)||n<0))return fail('GRID_UNITS');
r.units.forEach((units,column)=>lines.push({sourceRow:row+1,group:r.group,item:i.items[column],units}));
}
return {ok:true,value:{lines}};
}
// Original synthetic cases; expected outputs are literal records.
const cases = [
{
"label": "Grid to lines",
"input": {
"items": [
"A",
"B"
],
"rows": [
{
"group": "North",
"units": [
2,
0
]
}
]
},
"expected": {
"ok": true,
"value": {
"lines": [
{
"sourceRow": 1,
"group": "North",
"item": "A",
"units": 2
},
{
"sourceRow": 1,
"group": "North",
"item": "B",
"units": 0
}
]
}
}
},
{
"label": "Reject a short row",
"input": {
"items": [
"A",
"B"
],
"rows": [
{
"group": "North",
"units": [
2
]
}
]
},
"expected": {
"ok": false,
"error": "GRID_WIDTH"
}
},
{
"label": "Preserve an empty grid",
"input": {
"items": [
"A"
],
"rows": []
},
"expected": {
"ok": true,
"value": {
"lines": []
}
}
}
];
for (const sample of cases) {
const actual = orderGrid(sample.input);
assert.deepEqual(actual, sample.expected);
console.log(sample.label, JSON.stringify(actual));
}
判清邊界個案
North 只有 A 大於零,為何仍產生兩項?
查看參考答案
來源明確記 A=2、B=0,兩格都有資料。兩項都列 sourceRow=1;B 保留零數量,不能變成沒有記錄。