2016-02-24 2 views
0

У меня есть массив объектов с вложенным массивом объектов, такими как:Merge вложенного массива объектов в 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); 

ответ

1

Вот код

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>

0

Там может быть лучший способ сделать это, но это получает работу:

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 или некоторые такие), чтобы удалить «Детали» из ключей, но это сонный, где я;).

0

Если уплощение не будет работать, вы можете просто уменьшить. Здесь я строю каждый из автомобилей, заданных с помощью параметров в деталях, чтобы они могли оставаться мономорфными, пока они сплющиваются и за его пределами, если вы выберете.

В идеале, как у вас установлено состояние, не обязательно иметь отдельные ключи под деталями. Лучше избегать их вложенности или хранить на объектах, которые их действительно используют, если это так.

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>

Смежные вопросы