![](/img/trans.png)
[英]How to merge a nested array of objects in javascript with a specific shape
[英]Merge nested array of objects in JavaScript
我有一个带有嵌套对象数组的对象数组:
var cars = [
{
Plate: '112211',
Details:
[
{
Desc: 'Blah11 Blah Blah',
Miles: '111',
Color: 'blue'
},
{
Desc: 'Blah B22lah Blah',
Miles: '222',
Color: 'green'
},
],
Make:'Honda'
},
Plate: '223322',
Details:
[
{
Desc: 'Blah Blah B33lah',
Miles: '333',
Color: 'yellow'
},
{
Desc: 'Blah B44lah Blah',
Miles: '444',
Color: 'red'
}
],
Make:'GMC'
},
Plate: '334433',
Details:
[
{
Desc: 'Bl55ah Blah Blah',
Miles: '555',
Color: 'blue'
},
{
Desc: 'Blah B66lah Blah',
Miles: '666',
Color: 'pink'
},
],
Make:'Ford'
}
]
我正在尝试找到一种方法来将其转换为可以使嵌套数组变平或合并的新数组。 目标是拥有类似的东西:
[
{
Plate: '112211',
Desc: 'Blah11 Blah Blah',
Miles: '111',
Color: 'blue',
Make:'Honda'
},
{
Plate: '112211',
Desc: 'Blah B22lah Blah',
Miles: '222',
Color: 'green',
Make: 'Honda'
},
{
Plate: '223322',
Desc: 'Blah Blah B333lah',
Miles: '333',
Color: 'yellow'
Make: 'GMC'
},
{
Plate: '223322',
Desc: 'Blah Bl444ah B33lah',
Miles: '444',
Color: 'red',
Make: 'GMC'
},
{
Plate: '334433',
Desc: 'Bl555ah Blah B33lah',
Miles: '555',
Color: 'blue',
Make: 'Ford'
},
{
Plate: '334433',
Desc: 'Blah Bl666ah B33lah',
Miles: '666',
Color: 'pink',
Make: 'Ford'
},
]
lodash _.flatten和_.flattenDeep没有执行任何操作。 我也曾尝试做一个_.chain并展平以建立一个新的数组,但是结果是空的
var actions = _.chain(cars).flatten("Details");
for (i = 0; i < cars.length; i++) {
actions.each(function(action) {
list.push(cars[i].Plate);
list.push(action);
list.push(cars[i].Make);
这是代码
function merge(collection) { return _(collection).map(function(obj) { return _(obj) .pickBy(_.isArray) .values() .flatten() .map(function(dest) { return _.merge(dest, _.omitBy(obj, _.isArray)); }) .value(); }) .flatten() .value(); } var cars = [{ Plate: '112211', Details: [{ Desc: 'Blah11 Blah Blah', Miles: '111', Color: 'blue' }, { Desc: 'Blah B22lah Blah', Miles: '222', Color: 'green' }], Make: 'Honda' }, { Plate: '223322', Details: [{ Desc: 'Blah Blah B33lah', Miles: '333', Color: 'yellow' }, { Desc: 'Blah B44lah Blah', Miles: '444', Color: 'red' }], Make: 'GMC' }, { Plate: '334433', Details: [{ Desc: 'Bl55ah Blah Blah', Miles: '555', Color: 'blue' }, { Desc: 'Blah B66lah Blah', Miles: '666', Color: 'pink' }], Make: 'Ford' }]; var result = merge(cars); document.querySelector('#result').innerHTML = JSON.stringify(result, null, 2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.5.1/lodash.min.js"></script> <pre id="result"></pre>
也许有更好的方法可以做到这一点,但这可以完成工作:
var cars = [ { Plate: '112211', Details: [ { Desc: 'Blah11 Blah Blah', Miles: '111', Color: 'blue' }, { Desc: 'Blah B22lah Blah', Miles: '222', Color: 'green' }, ], Make:'Honda' }, { Plate: '223322', Details: [ { Desc: 'Blah Blah B33lah', Miles: '333', Color: 'yellow' }, { Desc: 'Blah B44lah Blah', Miles: '444', Color: 'red' } ], Make:'GMC' }, { Plate: '334433', Details: [ { Desc: 'Bl55ah Blah Blah', Miles: '555', Color: 'blue' }, { Desc: 'Blah B66lah Blah', Miles: '666', Color: 'pink' }, ], Make:'Ford' } ]; var details = []; _.each(cars, function(car) { var keys = _.keys(car); _.each(car.Details, function(dtl) { _.each(keys, function(key) { if (key !== 'Details') { dtl[key] = car[key]; } }); details.push(dtl); }); }); console.log(details); document.querySelector('#details').innerHTML = JSON.stringify(details); document.querySelector('#numDetails').innerHTML = details.length;
<script src="https://cdn.rawgit.com/lodash/lodash/3.0.1/lodash.min.js"></script> <div id="numDetails"></div> <div id="details"></div>
我确信有一种更干净的方法(使用_.filter
或类似的方法)从键中删除“ Details”,但是我在这里很困;)。
如果展平不起作用,则可以减小。 在这里,我详细地使用参数构造了给定的每辆汽车,以便它们在展平时可以保持单态性,如果您选择的话,也可以保持不变。
理想情况下,状态设置的方式不必在详细信息下包含单独的键。 如果是这样,避免嵌套它们或将它们保留在真正使用它们的对象上更简单。
function flattenCarList(prevCars, car) { var Details = car.Details; delete car.Details; var carProto = Object.create(car.prototype || null) var keys = Object.keys(Details); for (var i = 0; i < keys.length; i++) { Details[i] = carProto[i] = keys[i]; } var carSet = []; for (var i = 0; i < Details.length; i++) { carSet.push(new Details[i]); } return prevCars.concat(carSet); } var cars = [{ Make: 'Edzel', Plate: 123456, Details: { Desc: 'Don\\'t ask', Miles: 32, Colour: 'Sickly Green' } }]; // Now let's really get to the point. cars.reduce(flattenCarList); document.getElementById('status').innerHTML += 'RESULTS:<br />' + JSON.stringify(cars);
<code id="status"></code>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.