【问题标题】:Merge array of object dynamically with same key and create it as new data (array of object)使用相同的键动态合并对象数组并将其创建为新数据(对象数组)
【发布时间】:2021-03-20 18:36:50
【问题描述】:

我有一些对象数组 我想将具有相同键的对象数组合并并根据键和值将其创建为新对象

const data =[{
  date:"19",
  status:"in",
hour:”12:00”

},{

  date:"19",
  status:"in",
hour:”12:20”
},{
  date:"19",
  status:"in",
hour:”12:43”
},{
  date:"19",
  status:"out",
hour:”16:16”

},{
  date:"20",
  status:"in",
hour:07:30”
},{
  date:"20",
  status:"out",
hour:”14:40”
},{
  date:"21",
  status:"in",
hour:”08:12”
}
]

这是我想要的结果


result =[{
date:”19”,
hourIn= “12:00”,
hourOut= “16:16”,      
}, {
  date:"20",
  hourIn:"07:30",
hourOut:14:40”
},{
  date:"21",
hourIn:”08:12”,
hourOut:”-“}]

我想如何解决这个问题?

【问题讨论】:

  • 如果"status: "in""status": "out" 在不同的数组中,这将非常容易。我担心的是,不仅用最后一个覆盖"in",同时还保留最新的"out",这将非常困难
  • 是的,你是对的,但问题是我的后端工程师没有这样解决,也不想 -_-

标签: javascript algorithm filter array-merge arrayobject


【解决方案1】:

我是这样做的, 我遍历data,检查该日期是否已过。

如果不是,我检查了statusin 还是out,然后设置hourdate

如果已经通过,我检查status,然后检查小时是否早于hourIn或晚于hourOut已经设置。

let result={};
const data=[{date:"19",status:"in",hour:"12: 00"},{date:"19",status:"in",hour:"12:20"},{date:"19",status:"in",hour:"12:43"},{date:"19",status:"out",hour:"16:16"},{date:"20",status:"in",hour:"07:30"},{date:"20",status:"out",hour:"14:40"},{date:"21",status:"in",hour:"08:12"}];

data.forEach(({ date, status, hour }) => {
  if (date in result) {
    if (status == 'in' && hour < result[date].hourIn) result[date].hourIn = hour;
    else if (status == 'out' && hour > result[date].hourOut) result[date].hourOut = hour;
  } else result[date] = {
    date,
    hourIn: status == 'in' ? hour : '-',
    hourOut: status == 'out' ? hour : '-'
  };
});

result = Object.values(result);
console.log(result);

【讨论】:

    【解决方案2】:

    您正在尝试实现一个迷你 MapReduce。你可以谷歌了解更多详情。

    1. 创建一个 Map,其中键是您的日期,值是具有相同日期的对象数组。

    2. 现在通过将所有对象插入到地图中来按日期隔离它们。

    3. 根据 in、out 作为第一个条件和 time 作为第二个条件对数组进行排序。所以在每个数组中,第一个对象将是第一个对象,最后一个对象将是最后一个对象。

    4. 将每个数组简化为一个对象,取第一个和最后一个对象。

      让 map = new Map();

      for(让 d 的数据){ 让 t = map.get(d.date)||[]; t.push(d); map.set(d.date,t); }

      for(let v of map.values()){ v.sort((a,b)=>a.status

      让结果 = []

      for(let v of map.values()){ let reduce = // 从 v[0] v[v.length-1] 中获取 结果.push(减少); }

    【讨论】:

      【解决方案3】:

      既然我已经这样做了,我不确定它会增加多少,但这里有一种使用 reduce 的方法:

      const data = [
        {date:"19",status:"in",hour:"12:00"}, {date:"19",status:"in",hour:"12:20"}, {date:"19",status:"in",hour:"12:43"}, {date:"19",status:"out",hour:"16:16"},
        {date:"20",status:"in",hour:"07:30"}, {date:"20",status:"out",hour:"14:40"},
        {date:"21",status:"in",hour:"08:12"}
      ];
      
      const new_hour = (field, status, current, new_val) =>
        field === status &&
          (
            current === '-' ||
            (status === 'in') === (new_val < current)
          ) ? new_val : current;
      
      const hours_reducer = (acc, { date, status, hour }) =>
        Object.assign(acc, {
          [date]: {
            date,
            hourIn: new_hour('in', status, acc[date]?.hourIn || '-', hour),
            hourOut: new_hour('out', status, acc[date]?.hourOut || '-', hour),
          }
        });
      
      const values = Object.values( data.reduce(hours_reducer, {}) );
      
      console.log(values);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-24
        • 2021-07-27
        • 2020-10-03
        • 2020-10-04
        • 2022-01-01
        • 2021-12-27
        相关资源
        最近更新 更多