【问题标题】:Convert simple array into two-dimensional array (matrix)将简单数组转换为二维数组(矩阵)
【发布时间】:2011-05-28 09:39:31
【问题描述】:

假设我有一个数组:

A = Array(1, 2, 3, 4, 5, 6, 7, 8, 9);

我希望它转换成二维数组(N x M 的矩阵),例如这样:

A = Array(Array(1, 2, 3), Array(4, 5, 6), Array(7, 8, 9));

注意,矩阵的行和列是可变的。

【问题讨论】:

  • Array.prototype.toMatrix=function(per){return this.reduce(function(prev,current,i){if(i%per==0)prev.push([current]);else prev[prev.length-1].push(current);return prev;},[])}
  • const chunk = (xs, n) => xs.length < n ? [xs] : [xs .slice (0, n), ... chunk (xs .slice (n), n)]
  • 查看副本:"Convert a 1D array to 2D array" 以获得更多回复。

标签: javascript jquery arrays multidimensional-array


【解决方案1】:

这样的?

function listToMatrix(list, elementsPerSubArray) {
    var matrix = [], i, k;

    for (i = 0, k = -1; i < list.length; i++) {
        if (i % elementsPerSubArray === 0) {
            k++;
            matrix[k] = [];
        }

        matrix[k].push(list[i]);
    }

    return matrix;
}

用法:

var matrix = listToMatrix([1, 2, 3, 4, 4, 5, 6, 7, 8, 9], 3);
// result: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

【讨论】:

    【解决方案2】:

    您可以使用Array.prototype.reduce 函数在一行中完成此操作。

    ECMAScript 6 风格:

    myArr.reduce((rows, key, index) => (index % 3 == 0 ? rows.push([key]) 
      : rows[rows.length-1].push(key)) && rows, []);
    

    “普通”JavaScript:

    myArr.reduce(function (rows, key, index) { 
      return (index % 3 == 0 ? rows.push([key]) 
        : rows[rows.length-1].push(key)) && rows;
    }, []);
    

    您可以将 3 更改为任何您想要的列数,或者更好的是,将其放入可重用函数中:

    ECMAScript 6 风格:

    const toMatrix = (arr, width) => 
        arr.reduce((rows, key, index) => (index % width == 0 ? rows.push([key]) 
          : rows[rows.length-1].push(key)) && rows, []);
    

    “普通”JavaScript:

    function toMatrix(arr, width) {
      return arr.reduce(function (rows, key, index) { 
        return (index % width == 0 ? rows.push([key]) 
          : rows[rows.length-1].push(key)) && rows;
      }, []);
    }
    

    【讨论】:

    • 避免改变“rows”数组不是一个好主意吗? const toMatrix = (arr, width) => arr.reduce((rows, key, index) => (index % width === 0) ? [...rows, [key]] : [...rows. slice(0,-1), [...rows[rows.length -1], key]], []);
    • reduce() 函数中,回调的第一个参数是您将要返回的值。改变它并没有什么坏处,因为它只是为此而生的(用reduce() 的第二个参数初始化)。不需要额外的避免突变的开销(事实上,突变可能更高效)。它仍然可以称为“函数式”编程。
    【解决方案3】:

    此代码是通用的,无需担心大小和数组,通用

      function TwoDimensional(arr, size) 
        {
          var res = []; 
          for(var i=0;i < arr.length;i = i+size)
          res.push(arr.slice(i,i+size));
          return res;
        }
    
    1. 定义空数组。
    2. 根据大小进行迭代,这样我们就会得到指定的块。这就是为什么我用size递增i,因为大小可以是2,3,4,5, 6……
    3. 在这里,我首先从 i 切片到 (i+size),然后将其推送到空数组 res
    4. 返回二维数组。

    【讨论】:

      【解决方案4】:

      怎么样:

      var matrixify = function(arr, rows, cols) {
          var matrix = [];
          if (rows * cols === arr.length) {
              for(var i = 0; i < arr.length; i+= cols) {
                  matrix.push(arr.slice(i, cols + i));
              }
          }
      
          return matrix;
      };
      
      var a = [0, 1, 2, 3, 4, 5, 6, 7];
      matrixify(a, 2, 4);
      

      http://jsfiddle.net/andrewwhitaker/ERAUs/

      【讨论】:

        【解决方案5】:

        当我自己偶然发现这个时,我能想到的最干净的方法如下:

        const arrayToMatrix = (array, columns) => Array(Math.ceil(array.length / columns)).fill('').reduce((acc, cur, index) => {
          return [...acc, [...array].splice(index * columns, columns)]
        }, [])
        

        用法类似于

        const things = [
          'item 1', 'item 2',
          'item 1', 'item 2',
          'item 1', 'item 2'
        ]
        
        const result = arrayToMatrix(things, 2)
        

        结果最终在哪里

        [
          ['item 1', 'item 2'],
          ['item 1', 'item 2'],
          ['item 1', 'item 2']
        ]
        

        【讨论】:

        • 所以cur 根本不用?
        【解决方案6】:

        只需使用两个 for 循环:

        var rowNum = 3;
        var colNum = 3;
        var k = 0;
        var dest = new Array(rowNum);
        
        for (i=0; i<rowNum; ++i) {
          var tmp = new Array(colNum);
          for (j=0; j<colNum; ++j) {
            tmp[j] = src[k];
            k++;
          }
          dest[i] = tmp;
        }
        

        【讨论】:

        • 你能用C#重写一下吗?
        【解决方案7】:
        function matrixify( source, count )
        {
            var matrixified = [];
            var tmp;
            // iterate through the source array
            for( var i = 0; i < source.length; i++ )
            {
                // use modulous to make sure you have the correct length.
                if( i % count == 0 )
                {
                    // if tmp exists, push it to the return array
                    if( tmp && tmp.length ) matrixified.push(tmp);
                    // reset the temporary array
                    tmp = [];
                }
                // add the current source value to the temp array.
                tmp.push(source[i])
            }
            // return the result
            return matrixified;
        }
        

        如果你想实际替换一个数组的内部值,我相信你可以调用如下:

        source.splice(0, source.length, matrixify(source,3));
        

        【讨论】:

          【解决方案8】:

          这是一种将数组转换为二维数组的简单方法。

          function twoDarray(arr, totalPerArray) {
            let i = 0;
            let twoDimension = []; // Store the generated two D array
            let tempArr = [...arr]; // Avoid modifying original array
          
            while (i < arr.length) {
              let subArray = []; // Store 2D subArray
          
              for (var j = 0; j < totalPerArray; j++) {
                if (tempArr.length) subArray.push(tempArr.shift());
              }
          
              twoDimension[twoDimension.length] = subArray;
              i += totalPerArray;
            }
            return twoDimension;
          }
          const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
          
          twoDarray(arr, 3); // [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]

          【讨论】:

          • 请不要这样编码。很难看到发生了什么,而且代码不可重用也不通用。我建议看看这里介绍的其他解决方案,看看它们是如何工作的。
          • 嗨@RoyPrins。我已经修改了答案以包含一个更可重用的功能。 TY
          • 好节目!你甚至发现了你修改原始数组的地方。
          【解决方案9】:
          function changeDimension(arr, size) {  
            var arrLen = arr.length;
            var newArr = [];
            var count=0;
            var tempArr = [];
          
            for(var i=0; i<arrLen; i++) {
              count++;
              tempArr.push(arr[i]);
          
              if (count == size || i == arrLen-1) {
                newArr.push(tempArr);
                tempArr = [];
                count = 0;
              }    
            }  
            return newArr;
          }
          
          changeDimension([0, 1, 2, 3, 4, 5], 4);
          

          【讨论】:

          • 你能解释一下 if (count == size || i == arrLen-1) {...} 中发生了什么 - 当 i == arrLen-1 时会发生什么?
          【解决方案10】:
          function matrixify(array, n, m) {
              var result = [];
              for (var i = 0; i < n; i++) {
                  result[i] = array.splice(0, m);
              }
              return result;
          }
          a = matrixify(a, 3, 3);
          

          【讨论】:

            【解决方案11】:
            function chunkArrToMultiDimArr(arr, size) {
            
                var newArray = [];
            
                while(arr.length > 0)
                {
                  newArray.push(arr.slice(0, size));
                  arr = arr.slice(size);
                }
            
              return newArray;
            }
            
            //example - call function
            chunkArrToMultiDimArr(["a", "b", "c", "d"], 2);
            

            【讨论】:

              【解决方案12】:

              你可以像这样使用 push 和 slice

              var array = [1,2,3,4,5,6,7,8,9] ;
              var newarray = [[],[]] ;
              newarray[0].push(array) ;
              console.log(newarray[0]) ;
              

              输出将是

              [[1, 2, 3, 4, 5, 6, 7, 8, 9]]
              

              如果你想将数组分成3个数组

              var array = [1,2,3,4,5,6,7,8,9] ;
              var newarray = [[],[]] ;
              newarray[0].push(array.slice(0,2)) ;
              newarray[1].push(array.slice(3,5)) ;
              newarray[2].push(array.slice(6,8)) ;
              

              你可以使用拼接代替三行

              while(array.length) newarray.push(array.splice(0,3));
              

              【讨论】:

                【解决方案13】:
                const x: any[] = ['abc', 'def', '532', '4ad', 'qwe', 'hf', 'fjgfj'];
                
                // number of columns
                const COL = 3;
                
                const matrix = array.reduce((matrix, item, index) => {
                  if (index % COL === 0) {
                    matrix.push([]);
                  }
                
                  matrix[matrix.length - 1].push(item);  
                
                  return matrix;
                }, [])
                
                console.log(matrix);
                

                【讨论】:

                  【解决方案14】:

                  使用 Array.from() 的 ES6 最简单方法

                  const matrixify = (arr, size) => 
                  Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>  
                  arr.slice(i * size, i * size + size));
                  const list =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] ;
                  console.log(matrixify(list, 3));

                  【讨论】:

                    【解决方案15】:

                    又一次尝试,

                    1. 创建一个空矩阵(行数组数组)
                    2. 迭代arr并分配给匹配的行

                     function arrayToMatrix(arr, wantedRows) {
                          // create a empty matrix (wantedRows Array of Arrays] 
                          // with arr in scope
                          return new Array(wantedRows).fill(arr)
                            // replace with the next row from arr 
                            .map(() => arr.splice(0, wantedRows))
                        }
                    
                        // Initialize arr
                        arr = new Array(16).fill(0).map((val, i) => i)
                    
                        // call!!
                        console.log(arrayToMatrix(arr, 4));
                    
                        // Trying to make it nice
                        const arrToMat = (arr, wantedRows) => new Array(wantedRows).fill(arr)
                          .map(() => arr.splice(0, wantedRows))

                    (如:this one

                    (和:this one from other thread

                    MatArray 类?

                    扩展 Array 以添加到原型中,似乎很有用,它确实需要一些功能来补充 Array 方法,也许有一种情况需要一种 MatArray班级?也适用于多维垫子并将它们展平,也许,也许不是......

                    【讨论】:

                      【解决方案16】:

                      一维数组通过行数转换二维数组:

                      function twoDimensional(array, row) {
                          let newArray = [];
                          let arraySize = Math.floor(array.length / row);
                          let extraArraySize = array.length % row;
                          while (array.length) {
                            if (!!extraArraySize) {
                              newArray.push(array.splice(0, arraySize + 1));
                              extraArraySize--;
                            } else {
                              newArray.push(array.splice(0, arraySize));
                            }
                          }
                      
                          return newArray;
                        }
                      

                       function twoDimensional(array, row) {
                          let newArray = [];
                          let arraySize = Math.floor(array.length / row);
                          let extraArraySize = array.length % row;
                          while (array.length) {
                            if (!!extraArraySize) {
                              newArray.push(array.splice(0, arraySize + 1));
                              extraArraySize--;
                            } else {
                              newArray.push(array.splice(0, arraySize));
                            }
                          }
                      
                          return newArray;
                        }
                        
                        console.log(twoDimensional([1,2,3,4,5,6,7,8,9,10,11,12,13,14], 3))

                      【讨论】:

                        【解决方案17】:

                        简答用法:

                        const gridArray=(a,b)=>{const d=[];return a.forEach((e,f)=>{const 
                        h=Math.floor(f/b);d[h]=d[h]||[],d[h][f%b]=a[f]}),d};
                        

                        地点:

                        a: is the array
                        b: is the number of columns
                        

                        【讨论】:

                        • 短而丑。
                        【解决方案18】:

                        一个很棒的存储库here

                        • api:masfufa.js

                        • 示例:masfufa.html

                        根据该示例,以下 sn-p 解决了该问题:

                          jsdk.getAPI('my');
                          var A=[1, 2, 3, 4, 5, 6, 7, 8, 9];
                          var MX=myAPI.getInstance('masfufa',{data:A,dim:'3x3'});
                        

                        然后:

                        MX.get[0][0]  // -> 1 (first)
                        MX.get[2][2] //  ->9 (last)
                        

                        【讨论】: