我有一个对象
1:a
2:b
3:c
4:d
5:e
6:f
7:g
8:h
9:i
我想制作一个3D数组,比如
[
[ [a], [b], [c] ],
[ [d], [e], [f] ],
[ [g], [h], [i] ]
]
是否可以编写for-loop将前三个字母推送到3D数组,而不是后三个字母和第三个字母(如示例中所示)?
答案 0 :(得分:2)
根据@Andreas评论 Does JavaScript Guarantee Object Property Order? 。
无法保证对象中的属性顺序。因此,如果您需要依赖keyVal命令,则必须在Object.keys上执行新步骤:sorting。
解决方案可以基于Object.keys和模数运算符进行循环,以便按行或除以行排序:
var obj = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i'};
var resultByCol = [];
var resultByRow = [];
var objKeys = Object.keys(obj).sort(function(a, b) {
return a - b;
});
for (var idx = 0; idx < objKeys.length; idx++) {
var newIdx = idx % 3;
if (resultByCol[newIdx] === undefined) {
resultByCol.push([]);
}
resultByCol[newIdx].push([obj[objKeys[idx]]]);
newIdx = Math.floor(idx / 3);
if (resultByRow[newIdx] === undefined) {
resultByRow.push([]);
}
resultByRow[newIdx].push([obj[objKeys[idx]]]);
}
console.log('Grouped by Col: [');
for (var i = 0; i < resultByCol.length; i++) {
console.log('\t' + JSON.stringify(resultByCol[i]) + (((i + 1) == resultByCol.length) ? '' : ','));
}
console.log(']');
console.log('Grouped by Row: [');
for (i = 0; i < resultByRow.length; i++) {
console.log('\t' + JSON.stringify(resultByRow[i]) + (((i + 1) == resultByRow.length) ? '' : ','));
}
console.log(']');
&#13;
答案 1 :(得分:2)
您可以先对Object.keys()
数组进行排序,然后使用reduce()
按每3个键创建一个新数组。
var obj = {1: 'a',2: 'b',3: 'c',4: 'd',5: 'e',6: 'f',7: 'g',8: 'h',9: 'i',}
var result = Object.keys(obj).sort((a, b) => a - b).reduce(function(r, e, i) {
if(i % 3 == 0) r.push([]);
r[r.length - 1].push([obj[e]])
return r;
}, [])
console.log(result)
答案 2 :(得分:1)
使用keys
和简单的for
循环可以非常快速有效地实现这一目标,以保证代码的便捷性。
@ gaetanoM的解决方案可以很好地工作,但是对于更高效的功能,您可以执行以下操作:
var object = {1:'a', 2:'b', 3:'c', 4:'d', 5:'e', 6:'f', 7:'g', 8:'h', 9:'i'};
var keys = Object.keys(object);
var result = [];
for ( var i=, j=keys.length; i<j; i++){
result[i] = object[keys[i]];
}
答案 3 :(得分:1)
是。有很多方法可以做到这一点。可能最干净的是使用reduce()
函数:
const obj = { 1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i' };
const width = 3; // how many in each sub array.
const result = Object.keys(obj).map(key => obj[key]) // ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
.reduce((result, v) => {
if (result[result.length - 1].length === width) {
result.push([v]); // add new row
} else {
result[result.length - 1].push(v); // add to last row
}
return result;
}, [[]]);
console.log(result);
这需要更加冗长,但更容易理解。
首先,我将对象循环到map()
到正常数组。
然后,在reduce()
函数中,我用第一级嵌套数组启动它。然后在每个循环中,我检查结果中最后一个数组的长度。如果它已满,我为下一行添加一个新数组。否则,我只是将值添加到最后一行。
更紧凑的版本是:
const obj = { 1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i' };
const width = 3;
const result = Object.keys(obj).reduce((r, k) =>
r.concat(
r[r.length - 1].length === width
? [[obj[k]]]
: [r.pop().concat(obj[k])]
), [[]]);
console.log(result);
这个例子更多地使用了.concat()
,所以一切都在技术上在一条线上,但显然它更难以阅读和理解。