在JavaScript中合并嵌套的对象数组

时间:2016-02-24 04:06:18

标签: javascript arrays

我有一个带有嵌套数组对象的对象数组,如:

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);

3 个答案:

答案 0 :(得分:1)

这是代码

&#13;
&#13;
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);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.5.1/lodash.min.js"></script>
<pre id="result"></pre>
&#13;
&#13;
&#13;

答案 1 :(得分: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>或其他一些方法)从键中删除“详细信息”,但它在我所处的地方很困;)。

答案 2 :(得分:0)

如果扁平化不起作用,你可以减少。在这里,我使用参数详细描述了每辆车,如果您选择的话,它们可以保持单形,同时它们会变得扁平化。

理想情况下,您设置州的方式不应该在细节之下有单独的密钥。如果是这样的话,最好避免嵌套它们或将它们保存在真正使用它们的物体上。

&#13;
&#13;
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);
&#13;
<code id="status"></code>
&#13;
&#13;
&#13;