2017-02-21 21 views
2

У меня есть яваскрипт вложенного объекта, как показано ниже:извлечение и слияния массивов из вложенного объекта Javascript

input_data = { 
    "A1":{ 
     "B1":{ 
      "M1" : [ 
       {"E1":"10","E2":"11"}, 
       {"E1":"20","E2":"21"} 
      ], 
      "M2":[ 
       {"E1":"30","E2":"31"}, 
       {"E1":"40","E2":"41"} 
      ], 
      "M3":[ 
       {"E1":"50","E2":"51"} 
      ] 
     } 
    }, 
    "A2":{ 
     "B2":{ 
      "M1": [ 
       {"E1":"60","E2":"61"}, 
       {"E1":"70","E2":"71"} 
      ], 
      "M2":[ 
       {"E1":"80","E2":"81"}, 
       {"E1":"90","E2":"91"} 
      ] 
     } 
    } 
} 

мне нужно извлечь все пункты в разделе «M1», «М2», «М3» в массив, то есть, вывод должен быть таким, как показано ниже:

output_data = [ 
      {"E1":"10","E2":"11"}, 
      {"E1":"20","E2":"21"}, 
      {"E1":"30","E2":"31"}, 
      {"E1":"40","E2":"41"}, 
      {"E1":"50","E2":"51"}, 
      {"E1":"60","E2":"61"}, 
      {"E1":"70","E2":"71"}, 
      {"E1":"80","E2":"81"}, 
      {"E1":"90","E2":"91"} 
      ]; 

я мог бы добиться этого следующим образом:

var output_data = []; 
function traverse(obj) { 
    for (i in obj) { 
     if (!!obj[i] && typeof(obj[i])=="object") { 
      if (Array.isArray(obj[i])){ 
       output_data = output_data.concat([], obj[i]); 
      } 
      traverse(obj[i]); 
     } 
    } 
} 

traverse(input_data); 
console.log(output_data); 

является й лучший способ извлечения элементов дочернего массива и слияние в один?

+0

Если он работает для вас, то это принадлежит по Просмотр Кода. В этом случае я бы сказал, перемещаю массив output_data внутри функции и возвращаю его в нижней части функции после цикла for –

ответ

1

Вы можете использовать рекурсивный подход для вложенных объектов.

function flat(object) { 
 
    function f(o) { 
 
     Object.keys(o).forEach(function (k) { 
 
      if (!o[k]) { 
 
       return; 
 
      } 
 
      if (Array.isArray(o[k])) { 
 
       result = result.concat(o[k]); 
 
       return; 
 
      } 
 
      if (typeof o[k] === 'object') { 
 
       f(o[k]); 
 
      } 
 
     }); 
 
    } 
 
    var result = []; 
 
    f(object); 
 
    return result; 
 
} 
 

 
var input_data = { A1: { B1: { M1: [{ E1: "10", E2: "11" }, { E1: "20", E2: "21" }], M2: [{ E1: "30", E2: "31" }, { E1: "40", E2: "41" }], M3: [{ E1: "50", E2: "51" }] } }, A2: { B2: { M1: [{ E1: "60", E2: "61" }, { E1: "70", E2: "71" }], M2: [{ E1: "80", E2: "81" }, { E1: "90", E2: "91" }] } } }; 
 

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

+0

. Обертка возвращаемого массива - лучший подход. Благодаря! – nizantz

0

Вы можете использовать Array.prototype.map, Object.values и функция Flatten:

const input = { 
 
    "A1":{ 
 
     "B1":{ 
 
      "M1" : [ 
 
       {"E1":"10","E2":"11"}, 
 
       {"E1":"20","E2":"21"} 
 
      ], 
 
      "M2":[ 
 
       {"E1":"30","E2":"31"}, 
 
       {"E1":"40","E2":"41"} 
 
      ], 
 
      "M3":[ 
 
       {"E1":"50","E2":"51"} 
 
      ] 
 
     } 
 
    }, 
 
    "A2":{ 
 
     "B2":{ 
 
      "M1": [ 
 
       {"E1":"60","E2":"61"}, 
 
       {"E1":"70","E2":"71"} 
 
      ], 
 
      "M2":[ 
 
       {"E1":"80","E2":"81"}, 
 
       {"E1":"90","E2":"91"} 
 
      ] 
 
     } 
 
    } 
 
}; 
 

 
const values = Object.values.bind(Object); 
 
const output = flattenDeep(values(input).map((inner) => values(inner).map(values))); 
 

 
console.log(output); 
 

 
function flattenDeep(array) { 
 
    return array.reduce((flat, value) => { 
 
    if(Array.isArray(value)) { 
 
     flat.push(...flattenDeep(value)); 
 
    } else { 
 
     flat.push(value); 
 
    } 
 
    return flat; 
 
    }, []); 
 
}