javascript - 使用 reduce 计算以小时为单位的日期差异

标签 javascript arrays ecmascript-6

场景

我有一组对象,其中包含多个用户的出勤情况(准时、准时)。我正在尝试使用 Array .prototype .reduce() 来最小化代码。

以下是示例对象/数组,in 和 out 可以更多地取决于用户。

"temp": [
        {
            "name": "Test User",
            "id": 35,
            "Attendance": [
                {
                    "id": 34890,
                    "employee_code": "AL028",
                    "date": "2018-11-20",
                    "time": "2018-11-20T10:11:06.000Z",
                    "flag": "0\t1\t0\t0\t0",
                    "type": "IN"
                },
                {
                    "id": 34904,
                    "employee_code": "AL028",
                    "date": "2018-11-20",
                    "time": "2018-11-20T13:12:23.000Z",
                    "flag": "1\t1\t0\t0\t0",
                    "type": "OUT"
                },
                {
                    "id": 34914,
                    "employee_code": "AL028",
                    "date": "2018-11-20",
                    "time": "2018-11-20T13:46:18.000Z",
                    "flag": "0\t1\t0\t0\t0",
                    "type": "IN"
                },
                {
                    "id": 34943,
                    "employee_code": "AL028",
                    "date": "2018-11-20",
                    "time": "2018-11-20T16:00:02.000Z",
                    "flag": "1\t1\t0\t0\t0",
                    "type": "OUT"
                },
            ]
        }
  ]

代码

Please Ignore few variables which I've kept for logging purpose

let temp = attendances;
        let mappedAttendance = temp.map(emp => {
          let hours = 0,i=0;
          const empHours = emp.Attendance.reduce((firstEle, secondEle) => {
            if (
              firstEle.type === "IN" &&
              secondEle.type === "OUT" &&
              (firstEle !== undefined && secondEle !== undefined)
            ) {              
              hours +=
                Math.abs(
                  new Date(firstEle.time).getTime() -
                    new Date(secondEle.time).getTime()
                ) / 36e5;
            }            
            i++;
            return hours;            
          });          

          return {
            name: emp.name,
            id: emp.id,
            hours: empHours
          };
        });

目标

我也希望输出像下面这样

       {
            "name": "Test User",
            "id": 35,
            "hours": 3.0213888888888887
        },

问题

它似乎计算得不好,因为在第一次迭代后返回值将是 firstEle 并且它是在第一次迭代中计算的小时数并且它导致计算问题,我尝试了多种方法但我没有提出来以及如何减少工作量的解决方案。

更新

Karamell 的回答很完美,但我仍然很难在 reduce 中实现以下条件 此外,我设法通过以下方式获得了我想要的, 好像有 IN,OUT,OUT 它不会计算我想要的最后一个 OUT

          let hours = 0;          
          emp.Attendance.reduce((firstEle, secondEle) => {
            if (
              firstEle.type === "IN" &&
              secondEle.type === "OUT" &&
              (firstEle !== undefined && secondEle !== undefined)
            ) {
              hours +=
                Math.abs(
                  new Date(firstEle.time).getTime() -
                    new Date(secondEle.time).getTime()
                ) / 36e5;
            }
            return secondEle;
          });

最佳答案

如果你只是想要非常简洁的代码

emp.Attendance.reduce(
  ([result, lastIn], { time, type }) =>
    type === 'OUT' ? [result + (new Date(time) - lastIn)] : [result, new Date(time)],
  [0],
) /
  (1000 * 60 * 60);

它为您的数据返回 5.2502...,这可能是正确的。

您没有指定如果数据不匹配会发生什么,就输入/输出对而言,但这应该适用于正确的数据。

关于javascript - 使用 reduce 计算以小时为单位的日期差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56408916/

相关文章:

javascript - 单击元素并编辑内容(如文本区域)

c++ - 比较数组相似性的最佳比较算法是什么?

c - 用C打印二维手机键盘中的每个解锁图案

Javascript (ES6) 模块 : Is it possible to export a variable with a dynamic name?

javascript - 使用 JavaScript 打开 Chrome PDF 查看器对话

c# - 如何验证日期时间格式

javascript - 从数组中删除特定元素

javascript - 使用 ES6 导入节点模块时找不到模块的声明文件

javascript - es6中如何防止函数重写?

javascript - 如何更新自定义组件上的 onClick 引用?