可通过多种方式简化此功能?

时间:2019-04-07 05:18:23

标签: javascript arrays generalization

我正在尝试简化/概括遍历多维数组的函数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 ] ]

3 个答案:

答案 0 :(得分:1)

以下重写比原始文章更有效。

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]
// ];

答案 1 :(得分:1)

您可以使嵌套循环内的处理更加简洁。另外,我不明白为什么您需要忽略最后一列。

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);

答案 2 :(得分:1)

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)我更喜欢将数组作为参数发送,并返回它,即使我更改了数组也是如此。我的书中的代码更简洁,并且更易于调试。
e)使用变量(或方法)名称来解释正在发生的事情。
f)通过使用变量,更容易调试。
g)我通常给所有变量一个起始值来描述它们是哪种类型(空数组,对象,数字,字符串),以便下一个人可以查看它们并查看它们是什么,而不必阅读和处理什么变量名称意味着。