Source contract and expected records
This is an original, fully synthetic mapping example. Inputs are plain, acyclic JSON-shaped records with the fields shown; the canonical shape and rejection codes belong to this example. Adapt the contract before using a different source.
The original source uses unique, nonempty item labels as column headers. Every row supplies one nonnegative safe whole-number quantity per header. Expand every cell into a line with its source row, group and item; do not drop zero cells. A row with the wrong width rejects the whole mapping.
| Case | Input record (JSON) | Expected output (JSON) |
|---|---|---|
| Grid to lines | {"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}]}} |
| Reject a short row | {"items":["A","B"],"rows":[{"group":"North","units":[2]}]} | {"ok":false,"error":"GRID_WIDTH"} |
| Preserve an empty grid | {"items":["A"],"rows":[]} | {"ok":true,"value":{"lines":[]}} |
Run the local transformation
Run the complete example as a JavaScript module in Node.js. It contains the pure mapping function, all three inputs and literal expected outputs; assertions stop on a mismatch. A rejected case returns ok=false with an error code, rather than a partial canonical record.
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));
}
Work through the boundary
Why does North produce two lines although only A has a positive quantity?
Show the worked answer
The input explicitly records A=2 and B=0. Both cells are evidence. The two output lines share sourceRow=1; B remains a zero line rather than becoming absent.