在 2D JavaScript 数组周围添加填充
Posted
技术标签:
【中文标题】在 2D JavaScript 数组周围添加填充【英文标题】:Adding padding around a 2D JavaScript array 【发布时间】:2022-01-23 06:47:03 【问题描述】:我正在尝试创建一个用零填充二维数组的函数。我做了以下功能:
function addPadding(arr)
var a = new Array(arr.length + 2).fill(0)
//left and right padding
arr.forEach(el =>
el.push(0)
el.unshift(0)
)
//top padding
arr.unshift(a)
//bottom padding
arr.push(a)
return arr;
console.table(addPadding(addPadding([[1,2],[3,4]])));
如果我只调用一次,该函数可以正常工作,但如果我调用它两次,就像在这个例子中一样,我会得到下表:
我的函数有一个意外结果,它为 2 行添加了额外的零。有谁知道为什么会这样?
【问题讨论】:
【参考方案1】:第一次在 same 数组a
的顶部和底部填充。这意味着同一个数组第二次被填充(左右)两次。
通过复制避免添加 same 数组。
变化:
arr.push(a)
到:
arr.push([...a])
【讨论】:
【参考方案2】:@trincot 的回答很好,我只是想提出这种语法:
function addPadding(arr)
const a = new Array(arr.length + 2).fill(0)
return [a, ...arr.map(el => [0, ...el, 0]), a]
const arr = addPadding(addPadding([[1,2],[3,4]]))
arr.forEach(el => document.write(el + '<br>'))
【讨论】:
【参考方案3】:为了让你的函数是幂等的,你需要检查你的数组是否已经被填充。您可以通过检查所有“外边缘”是否为 0 来做到这一点。您可以认为这是一个“框架”:
const getFrame = (arr) =>
const topEdge = arr[0];
const bottomEdge = arr[arr.length-1];
const leftEdge = arr.map(row => row[0]);
const rightEdge = arr.map(row => row[row.length-1]);
return [topEdge, bottomEdge, leftEdge, rightEdge];
;
现在我们简单地遍历框架,看看是否所有的值都为零:
const isAllZeros = (frame) =>
return frame.every(edge =>
return edge.every(n =>
return (n === 0);
);
);
;
现在我们知道何时填充或不填充。所以我们编写了填充函数:
const padArray = (arr) =>
let newArray = [];
let firstAndLastRow = new Array(arr[0].length+2).fill(0);
newArray.push(firstAndLastRow);
arr.forEach(oldRow =>
let newRow = Array.from(oldRow);
newRow.unshift(0);
newRow.push(0);
newArray.push(newRow);
);
newArray.push(firstAndLastRow);
return newArray;
;
const getFrame = (arr) =>
const topEdge = arr[0];
const bottomEdge = arr[arr.length-1];
const leftEdge = arr.map(row => row[0]);
const rightEdge = arr.map(row => row[row.length-1]);
return [topEdge, bottomEdge, leftEdge, rightEdge];
;
const isAllZeros = (frame) =>
return frame.every(edge =>
return edge.every(n =>
return (n == 0);
);
);
;
const padArray = (arr) =>
let newArray = [];
let firstAndLastRow = new Array(arr[0].length+2).fill(0);
newArray.push(firstAndLastRow);
arr.forEach(oldRow =>
let newRow = Array.from(oldRow);
newRow.unshift(0);
newRow.push(0);
newArray.push(newRow);
);
newArray.push(firstAndLastRow);
return newArray;
;
// debugging stuff
const rowsEl = document.getElementById('rows');
const colsEl = document.getElementById('cols');
const generateButton = document.getElementById('gen');
const padButton = document.getElementById('pad');
const vis = document.getElementById('vis');
const dbg = document.getElementById('dbg');
let arr2d = [];
generateButton.addEventListener('click', () =>
const rows = rowsEl.valueAsNumber;
const cols = colsEl.valueAsNumber;
arr2d = [];
for (let row=0; row<rows; row++)
let thisRow = [];
for (let col=0; col<cols; col++)
thisRow.push(Math.floor(Math.random()*10));
arr2d.push(thisRow);
showArray(arr2d);
);
padButton.addEventListener('click', () =>
const frame = getFrame(arr2d);
const isPadded = isAllZeros(frame);
if (!isPadded)
arr2d = padArray(arr2d);
showArray(arr2d);
);
const showArray = (arr) =>
let txt = '';
arr.forEach(row =>
txt += "\n" + `$row.join(" ")`;
);
vis.innerText = txt;
const frame = getFrame(arr2d);
const isPadded = isAllZeros(frame);
;
<form name=f id=f>
<table>
<tr>
<td><label for=rows>rows</label></td>
<td><input type=number name=rows id=rows value=3 /></td>
</tr>
<tr>
<td><label for=cols>cols</label></td>
<td><input type=number name=cols id=cols value=3 /></td>
</tr>
<tr>
<td><button id=gen type=button>generate</button></td>
<td><button id=pad type=button>pad</button></td>
</tr>
</table>
</form>
<pre id="vis"></pre>
【讨论】:
以上是关于在 2D JavaScript 数组周围添加填充的主要内容,如果未能解决你的问题,请参考以下文章