从嵌套的对象数组

时间:2016-10-21 18:31:24

标签: 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:  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);
    }
}

这是我想要实现的最终结果:

arrIDs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];

我可能需要最多3或4个嵌套级别,但如果无法优化更多,我可能会使用不同的结构将其降低到2级。

我想要最优化的是实际上所有那些在for循环中的Array()。push()调用。

有没有人知道这样做的好方法?

修改

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

3 个答案:

答案 0 :(得分:1)

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

&#13;
&#13;
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(function(r, o) {
  r = r.concat(o.second.map(function(e) {
    return e.id;
  }))
  return r;
}, []);
console.log(result)
&#13;
&#13;
&#13;

ES6版

&#13;
&#13;
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.concat(o.second.map(e => e.id)) , []);
console.log(result)
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可以使用迭代和递归提议。这种方法适用于任何级别。

&#13;
&#13;
function getValues(o, key) {
    return o !== null && typeof o === 'object' && Object.keys(o).reduce(function (r, k) {
        return 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: 10 }, { id: 11 }, { id: 12 }] }];

console.log(getValues(first, 'id'));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您可以使用此递归ES6功能。它适用于任何级别,您可以传递一个数组,普通对象或其他任何东西(在后一种情况下,您得到一个空数组作为结果):

function getAll(obj, key) {
    return obj !== Object(obj) ? [] 
        : Object.keys(obj).reduce ( (acc, k) => 
            acc.concat(k == key ? obj[k] : getAll(obj[k], key)), [] ); 
}

// sample data with different levels and mix of array / object alterations
var first = [
  { a: 2, id:  1}, { second: [ { id:  2}, { id:  3} ] },
  { second: [ { id:  4}, { id:  5}, { id:  6} ] },
  { second: [ { id:  7}, { third: {id:  6}}, { id:  9} ] },
  { second: [ { id: 10}, { id: 11}, { id: 12} ] }
];

var result = getAll(first, 'id');

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

对于IE8兼容性:

function getAll(obj, key) {
    if (typeof obj != 'object' || obj == null) return [];
    var acc = [];
    for (var k in obj) {
        acc = acc.concat( k == key ? obj[k] : getAll(obj[k], key) );
    }
    return acc; 
}

// sample data with different levels and mix of array / object alterations
var first = [
  { a: 2, id:  1}, { second: [ { id:  2}, { id:  3} ] },
  { second: [ { id:  4}, { id:  5}, { id:  6} ] },
  { second: [ { id:  7}, { third: {id:  6}}, { id:  9} ] },
  { second: [ { id: 10}, { id: 11}, { id: 12} ] }
];

var result = getAll(first, 'id');

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }