这个功能有多少种方式可以简化?
In how many ways can this function be simplified?
我正在尝试 simplify/generalize 函数 foo_one
遍历多维数组并将除第一个元素之外的所有子数组元素设置为具有 null
值。
我只得到了第一个功能,然后我应该找到更多的方法来概括它,以仍然实现 foo_one
的预期目的。
如有任何建议,我们将不胜感激。
我已经实现了该功能的其他 2 个变体,如果可能的话,我希望拥有更多变体。
var arr = [
[2, null, 2, null],
[2, null, 2, null],
[null, null, null, null],
[null, null, null, null]
];
function foo_one() {
for (let y = 0; y < arr.length - 1; y++) {
for (let x = 0; x < arr.length - 1; x++) {
if (arr[x + 1][y] != null) {
if (arr[x + 1][y] == arr[x][y]) {
arr[x][y] = arr[x][y] * 2;
arr[x + 1][y] = null;
}
if (arr[x][y] == null) {
arr[x][y] = arr[x + 1][y];
arr[x + 1][y] = null;
}
}
}
}
}
function foo_two() {
for (let y = 0; y < arr.length - 1; y++) {
for (let x = 0; x < arr.length - 1; x++) {
if (arr[x + 1][y] != null && arr[x + 1][y] == arr[x][y]) {
arr[x][y] = arr[x][y] * 2;
arr[x + 1][y] = null;
}
}
}
}
function foo_three() {
for (let y = 0; y < arr.length - 1; y++) {
for (let x = 0; x < arr[y].length - 1; x++) {
if (arr[x + 1][y] != null && arr[x + 1][y] == arr[x][y]) {
arr[x][y] = arr[x][y] * 2;
arr[x + 1][y] = null;
}
}
}
}
// Output
[ [ 4, null, 4, null ],
[ null, null, null, null ],
[ null, null, null, null ],
[ null, null, null, null ] ]
下面的重写比原来的post更高效。
let arr = [
[2, null, 2, null],
[2, null, 2, null],
[null, null, null, null],
[null, null, null, null]
];
function foo_four(arr) {
for (let y = 0, yl = arr.length - 1; y < yl; y++) {
let currRow = arr[y];
let nextRow = arr[y + 1];
for (let x = 0, xl = nextRow.length - 1; x < xl; x++) {
let currValue = currRow[x];
if (currValue && currValue === nextRow[x]) {
currRow[x] = currValue * 2;
nextRow[x] = null;
}
}
}
}
foo_four(arr);
console.log(arr);
// [
// [4, null, 4, null],
// [null, null, null, null],
// [null, null, null, null],
// [null, null, null, null]
// ];
可以让嵌套循环内部的处理更加简洁。另外,我不明白你为什么需要忽略最后一列。
function foo_four() {
for (let y = 0; y < arr.length; y++) {
for (let x = 0; x < arr.length - 1; x++) {
arr[x][y] = arr[x][y] === null ? arr[x+1][y] : arr[x][y] * 2;
arr[x + 1][y] = null;
}
}
}
var arr = [
[2, null, 2, null],
[2, null, 2, null],
[null, null, null, null],
[null, null, null, null]
];
foo_four();
console.log(arr);
function foo_four(arr) {
let yLoopCount = arr.length - 1,
xArrLength = 0,
currentRowValue = 0,
nextRowValue = 0;
for (let y = 0; y < yLoopCount; y++) {
xArrLength = arr[y].length; // arr[y].length - 1
for (let x = 0; x < xArrLength; x++) {
currentRowValue = arr[y][x];
nextRowValue = arr[y+1][x];
if (currentRowValue && currentRowValue == nextRowValue) {
arr[y][x] = currentRowValue * 2;
arr[y+1][x] = null;
}
}
return arr;
}
var arr = [
[2, null, 2, null],
[2, null, 2, null],
[null, null, null, null],
[null, null, null, null]
];
foo_four();
// Output
// [
// [4, null, 4, null],
// [null, null, null, null],
// [null, null, null, null],
// [null, null, null, null]
// ];
a) 我也在循环最后一行。
b) 如果在循环外创建变量,然后重用它们,这是一个小的优化。
c) 如果您使用变量来缩短任何类型的深度引用,那么这是一个小的优化。深入研究每个子属性需要时间,比如多次引用 arr[y][x]
而不是 currentRowValue
.
d) 我更喜欢将数组作为参数发送,并且 return 它,即使我更改了数组。我书中的代码更清晰,更易于调试。
e) 使用变量(或方法)名称来解释发生了什么。
f) 通过使用变量,更容易调试
g) 我通常给所有变量一个起始值来描述它们的类型(空数组、对象、数字、字符串),这样下一个人就可以查看它们并了解它们是什么,而不必读取和处理变量的内容名字的意思。
我正在尝试 simplify/generalize 函数 foo_one
遍历多维数组并将除第一个元素之外的所有子数组元素设置为具有 null
值。
我只得到了第一个功能,然后我应该找到更多的方法来概括它,以仍然实现 foo_one
的预期目的。
如有任何建议,我们将不胜感激。
我已经实现了该功能的其他 2 个变体,如果可能的话,我希望拥有更多变体。
var arr = [
[2, null, 2, null],
[2, null, 2, null],
[null, null, null, null],
[null, null, null, null]
];
function foo_one() {
for (let y = 0; y < arr.length - 1; y++) {
for (let x = 0; x < arr.length - 1; x++) {
if (arr[x + 1][y] != null) {
if (arr[x + 1][y] == arr[x][y]) {
arr[x][y] = arr[x][y] * 2;
arr[x + 1][y] = null;
}
if (arr[x][y] == null) {
arr[x][y] = arr[x + 1][y];
arr[x + 1][y] = null;
}
}
}
}
}
function foo_two() {
for (let y = 0; y < arr.length - 1; y++) {
for (let x = 0; x < arr.length - 1; x++) {
if (arr[x + 1][y] != null && arr[x + 1][y] == arr[x][y]) {
arr[x][y] = arr[x][y] * 2;
arr[x + 1][y] = null;
}
}
}
}
function foo_three() {
for (let y = 0; y < arr.length - 1; y++) {
for (let x = 0; x < arr[y].length - 1; x++) {
if (arr[x + 1][y] != null && arr[x + 1][y] == arr[x][y]) {
arr[x][y] = arr[x][y] * 2;
arr[x + 1][y] = null;
}
}
}
}
// Output
[ [ 4, null, 4, null ],
[ null, null, null, null ],
[ null, null, null, null ],
[ null, null, null, null ] ]
下面的重写比原来的post更高效。
let arr = [
[2, null, 2, null],
[2, null, 2, null],
[null, null, null, null],
[null, null, null, null]
];
function foo_four(arr) {
for (let y = 0, yl = arr.length - 1; y < yl; y++) {
let currRow = arr[y];
let nextRow = arr[y + 1];
for (let x = 0, xl = nextRow.length - 1; x < xl; x++) {
let currValue = currRow[x];
if (currValue && currValue === nextRow[x]) {
currRow[x] = currValue * 2;
nextRow[x] = null;
}
}
}
}
foo_four(arr);
console.log(arr);
// [
// [4, null, 4, null],
// [null, null, null, null],
// [null, null, null, null],
// [null, null, null, null]
// ];
可以让嵌套循环内部的处理更加简洁。另外,我不明白你为什么需要忽略最后一列。
function foo_four() {
for (let y = 0; y < arr.length; y++) {
for (let x = 0; x < arr.length - 1; x++) {
arr[x][y] = arr[x][y] === null ? arr[x+1][y] : arr[x][y] * 2;
arr[x + 1][y] = null;
}
}
}
var arr = [
[2, null, 2, null],
[2, null, 2, null],
[null, null, null, null],
[null, null, null, null]
];
foo_four();
console.log(arr);
function foo_four(arr) {
let yLoopCount = arr.length - 1,
xArrLength = 0,
currentRowValue = 0,
nextRowValue = 0;
for (let y = 0; y < yLoopCount; y++) {
xArrLength = arr[y].length; // arr[y].length - 1
for (let x = 0; x < xArrLength; x++) {
currentRowValue = arr[y][x];
nextRowValue = arr[y+1][x];
if (currentRowValue && currentRowValue == nextRowValue) {
arr[y][x] = currentRowValue * 2;
arr[y+1][x] = null;
}
}
return arr;
}
var arr = [
[2, null, 2, null],
[2, null, 2, null],
[null, null, null, null],
[null, null, null, null]
];
foo_four();
// Output
// [
// [4, null, 4, null],
// [null, null, null, null],
// [null, null, null, null],
// [null, null, null, null]
// ];
a) 我也在循环最后一行。
b) 如果在循环外创建变量,然后重用它们,这是一个小的优化。
c) 如果您使用变量来缩短任何类型的深度引用,那么这是一个小的优化。深入研究每个子属性需要时间,比如多次引用 arr[y][x]
而不是 currentRowValue
.
d) 我更喜欢将数组作为参数发送,并且 return 它,即使我更改了数组。我书中的代码更清晰,更易于调试。
e) 使用变量(或方法)名称来解释发生了什么。
f) 通过使用变量,更容易调试
g) 我通常给所有变量一个起始值来描述它们的类型(空数组、对象、数字、字符串),这样下一个人就可以查看它们并了解它们是什么,而不必读取和处理变量的内容名字的意思。