Javascript 从嵌套的对象阵列优化阵列构建

Javascript 从嵌套的对象阵列优化阵列构建,javascript,arrays,object,Javascript,Arrays,Object,我想优化从对象数组中提取属性值的过程,在Javascript中,每个对象都包含其他嵌套的对象数组 我真的不知道如何用文字来解释,所以这里有一些代码来解释我试图优化的内容: // test case var first = [ { second: [ { id: 1}, { id: 2}, { id: 3} ] }, { second: [ { id: 4}, { id: 5}, { id: 6} ] }, { second: [ { id: 7}, { id

我想优化从对象数组中提取属性值的过程,在Javascript中,每个对象都包含其他嵌套的对象数组

我真的不知道如何用文字来解释,所以这里有一些代码来解释我试图优化的内容:

// test case
var first = [
    { second: [ { id:  1}, { id:  2}, { id:  3} ] },
    { second: [ { id:  4}, { id:  5}, { id:  6} ] },
    { second: [ { id:  7}, { id:  8}, { id:  9} ] },
    { second: [ { id: 10}, { id: 11}, { id: 12} ] }
];

// where the id values will be stored
var arrIDs = [];

// extracting the id values
for (var i=0; i<first.length; i++){
    for (var j=0; j<first[j].second.length; j++){
        // I want to avoid all these push() calls
        arrIDs.push(first[j].second[j].id);
    }
}
我可能需要3或4个嵌套级别,但如果不可能优化更多,我可以使用不同的结构将其减少到2个级别

我最想优化的实际上是for循环中所有的Array().push()调用

有人知道这样做的好方法吗

编辑


我忘了提到我需要在IE8是我们最好的选择的环境中使用它。因此ES6不是一个选项。

对于您的数据结构,您可以使用
reduce()
map()

var first=[
{second:[{id:1},{id:2},{id:3}]},
{second:[{id:4},{id:5},{id:6}]},
{second:[{id:7},{id:6},{id:9}]},
{second:[{id:10},{id:11},{id:12}]}
];
var result=first.reduce(函数(r,o){
r=r.concat(o.second.map)(函数(e){
返回e.id;
}))
返回r;
}, []);

log(result)
您可以使用迭代和递归方案。这种方法适用于任何级别

函数获取值(o,键){
返回o!==null&&typeof o==='object'&&object.keys(o).reduce(函数(r,k){
返回r.concat(k==key?o[k]:getValues(o[k],key));
}, []) || [];
}
var first=[{second:[{id:1},{id:2},{id:3}]},{second:[{id:4},{id:5},{id:6}]},{second:[{id:7},{id:6},{id:9}},{second id:[{id:10},{id:11},{id:12}];
log(getValues(第一个'id'))

。作为控制台包装{max height:100%!important;top:0;}
您可以使用此递归ES6函数。它适用于任何级别,您可以向其传递数组、普通对象或任何其他内容(在后一种情况下,结果是得到一个空数组):

函数getAll(对象,键){
返回对象!==对象(对象)?[]
:Object.keys(obj).reduce((acc,k)=>
acc.concat(k==key?obj[k]:getAll(obj[k],key)),[]);
}
//具有不同级别和混合阵列/对象更改的示例数据
var first=[
{a:2,id:1},{second:[{id:2},{id:3}]},
{second:[{id:4},{id:5},{id:6}]},
{second:[{id:7},{second:{id:6},{id:9}]},
{second:[{id:10},{id:11},{id:12}]}
];
var result=getAll(第一个“id”);
控制台日志(结果)

。作为控制台包装{最大高度:100%!重要;顶部:0;}
请添加第三或第四级的外观。与第一或第二级相同。每个第二层都有一个属性,其中包含一个数组,数组的每个字段都是另一个对象,以此类推,最深可达4层。看起来很整洁,但我需要在最多可以使用IE8的环境中使用它。ES6在IE<9中不可用。但仍然是一个很好的解决方案:)啊,这就像是重要的信息。你能把它添加到你的问题中吗?在问题中添加了关于ES6的注释。代码的兼容性版本看起来也很好。谢谢你花时间讨论这件事!通过查看评论中的解决方案,对每个解决方案进行基准测试,似乎这个解决方案是最好的。但是,它是否需要ES6?我运行它的环境最多只有IE8,而ES6不可用……这不是和for循环一样,只是写得不同吗?我的意思是,有两个forEach()调用,它只是(var i=0;i任何循环方法都是一种具有特殊功能的for-loop方法,比如迭代、映射、过滤、使用量化器或归约。问题是,哪种方法更适合。你说得对,无论你如何编写循环,循环都是循环。
arrIDs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];