如何从具有重复值的数组中嵌套对象

时间:2019-01-17 13:11:01

标签: javascript arrays object

我有一系列用于公交车到达的物品。该数组的对象具有重复属性,但时间不同。我想将后来出现的总线嵌套到首先出现的总线中。数组也按到达时间排序。

[ 
   { Arrival, busId: "123", minToStop: 16, timeToStop: 957 },
   { Arrival, busId: "123", minToStop: 23, timeToStop: 1390 } 
]

在javascript中是否有任何简便的方法?

这就是我想要的

[ 
   { Arrival, busId: "123", minToStop: 16, timeToStop: 957, laterBuses: 
      [
         { Arrival, busId: "123", minToStop: 23, timeToStop: 1390 },
         { Arrival, busId: "123", minToStop: 30, timeToStop: 1820 }
      ]
   }
]

2 个答案:

答案 0 :(得分:1)

您可以将数组reduce设为一个值(Map),然后spread将该映射的值作为新数组:

const busses = [
  { busId: '234', minToStop: 40, timeToStop: 1390 },
  { busId: '123', minToStop: 16, timeToStop: 957 },
  { busId: '123', minToStop: 23, timeToStop: 1490 },
  { busId: '234', minToStop: 17, timeToStop: 957 },
  { busId: '123', minToStop: 40, timeToStop: 1390 },
  { busId: '123', minToStop: 30, timeToStop: 1390 },
  { busId: '234', minToStop: 1, timeToStop: 1490 },
];
console.log([
  ...busses
    .sort((a, b) => a.minToStop - b.minToStop)
    .reduce((result, bus) => {
      const parentBus = result.get(bus.busId);
      const current = parentBus || {
        ...bus,
        laterBusses: [],
      };
      if (!!parentBus) {
        //only add to laterbusses if it's not the first bus found
        current.laterBusses.push(bus);
      }
      return result.set(current.busId, current);
    }, new Map())
    .values(),
]);

答案 1 :(得分:0)

此解决方案将首先按minToStop对总线进行排序,然后按busId对总线进行排序。然后,它会遍历buses数组,并有条件地将总线放在final数组的顶层或按您的要求嵌套。

const buses = [ 
   { busId: "234", minToStop: 40, timeToStop: 1390 },
   { busId: "123", minToStop: 16, timeToStop: 957 },
   { busId: "123", minToStop: 23, timeToStop: 1490 },
   { busId: "234", minToStop: 17, timeToStop: 957 },
   { busId: "123", minToStop: 30, timeToStop: 1390 },
   { busId: "234", minToStop: 1, timeToStop: 1490 } 
];

buses.sort((a,b) => a.minToStop - b.minToStop);
buses.sort((a,b) => a.busId > b.busId);

let formatted = [];

buses.forEach(bus => {
  if (
    formatted.length > 0 && 
    formatted[formatted.length - 1].busId === bus.busId
  ) {
    formatted[formatted.length - 1].laterBuses.push(bus);
  } else {
    bus.laterBuses = [];
    formatted.push(bus);
  }
});

console.log(formatted);