将简单数组转换为二维数组(矩阵)
Posted
技术标签:
【中文标题】将简单数组转换为二维数组(矩阵)【英文标题】: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" 以获得更多回复。
【参考方案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;
-
定义空数组。
根据大小进行迭代,这样我们就会得到指定的块。这就是为什么我用size递增i,因为大小可以是2,3,4,5, 6……
在这里,我首先从 i 切片到 (i+size),然后将其推送到空数组 res。
返回二维数组。
【讨论】:
【参考方案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】:又一次尝试,
-
创建一个空矩阵(行数组数组)
迭代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)
【讨论】:
以上是关于将简单数组转换为二维数组(矩阵)的主要内容,如果未能解决你的问题,请参考以下文章