代码之家  ›  专栏  ›  技术社区  ›  alt-rock

不可变地调整2d数组的大小

  •  2
  • alt-rock  · 技术社区  · 7 年前

    演示: https://jsfiddle.net/yxm9d4L0/2/

    let arr = [
        [null, null, null],
        [null, {'hello': 'world'}, null],
        [null, null, null]
    ]
    

    width = 10; height = 8;
    

    或小于当前长度:

    width = 1; height = 2;
    

    默认填充值为 null

    immutably 基于新的宽度或高度?

    function handleArrUpdate(h,w) {
      let currentArr = [
        [null, null, null],
        [null, {'hello': 'world'}, null],
        [null, null, null]
      ];
      let currentArrWidth = currentArr[0].length;
      let currentArrHeight = currentArr.length;
      let updatedArr = [...currentArr];
    
      if (h > currentArrHeight) {
        let arr = createArray(w, null);
        for (let i = 0; i <= h; i++) {
          updatedArr.concat(arr)
        }
      } else if (h < currentArrHeight) {
        let arr = createArray(w, null);
        for (let i = 0; i <= h; i++) {
          updatedArr.concat(arr)
        }
      }
    
      if (w > currentArrWidth) {
        let arr = createArray(w, null);
        for (let i = 0; i <= h; i++){
          updatedArr[i].concat(arr)
        }
      } else if (w < currentArrWidth) {
        let arr = createArray(w, null);
        for (let i = 0; i <= h; i++) {
          updatedArr[i].concat(arr)
        }
      }
    
      console.log('updated array', updatedArr);
    
      function createArray(size, defaultVal) {
        let arr = new Array(size);
        for (let i = 0; i < size; i++) {
          arr[i] = defaultVal;
        }
        return arr;
      }
    }
    
    handleArrUpdate(10,8);
    handleArrUpdate(1,2);
    handleArrUpdate(3,3);

    目前,此代码仅适用于连接更高的值。我越来越 Cannot read property 'concat' of undefined .

    //10x8
    [
        [null, null, null, null, null, null, null, null, null, null],
        [null, { 'hello': 'world' }, null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null, null, null]
    ];
    
    // 1x2
    [
        [null, null]
    ]
    
    // 3x3
    [
        [null, null, null],
        [null, { 'hello': 'world' }, null],
        [null, null, null]
    ]
    // 4x2
    [
        [null, null],
        [null, { 'hello': 'world' }],
        [null, null],
        [null, null]
    ]
    
    2 回复  |  直到 7 年前
        1
  •  0
  •   jo_va    7 年前

    Array.from . 但是,它将复制现有内容,因此对象引用将被复制,并且仍然指向相同的对象。

    const arr = [
      [null, null, null],
      [null, {'hello': 'world'}, null],
      [null, null, null]
    ];
    
    function resize(arr, width, height, val = null) {
      const newRow = row => Array.from({ length: width }, (_, i) => {
        return i < row.length ? row[i] : val
      });
      return Array.from({ length: height }, (_, i) => {
        return i < arr.length ? newRow(arr[i]) : Array.from({ length: width }, () => val);
      });
    }
    
    console.log(JSON.stringify(resize(arr, 5, 5, 0)));
    console.log(JSON.stringify(resize(arr, 2, 4, null)));
        2
  •  0
  •   Code Maniac    7 年前

    您可以根据宽度和高度使用过滤器和推送。

    function handleArrUpdate(h,w) {
      let currentArr = [[null, null, null],[null, {'hello': 'world'}, null],[null, null, null]];
      let op = currentArr.map(e => {
       return  e.length > w ? e.filter( (_, index ) => index < w) : e.concat( new Array ( w - e.length ).fill( null ))
      })
      if(h > currentArr.length){
        let temp = h-currentArr.length
        while(temp--)op.push( new Array(w).fill(null) )
      } else {
        op = op.filter( ( _, index ) => index < h )
      }
      return op
    }
    
    //console.log(handleArrUpdate(10,8));
    console.log(handleArrUpdate(1,2));
    console.log(handleArrUpdate(3,3))