记一次逻辑代码的实现(数组内数据按照指定时间差进行分组)

业务场景

有如下数据:

  id        intime       outtime1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26
1190771865,2019-11-26 16:42:46,2019-11-26 16:42:46
1190771865,2019-11-26 17:23:11,2019-11-26 17:23:11
1190771865,2019-11-26 13:27:26,2019-11-26 13:27:26

需求:

  针对以上数据进行重组,重组规则为:

    对以上数据进行intime升序排序,后一条数据与前一条数据的intime进行比较

    1、如果第二条与第一条数据的差值大于120min,则直接舍弃第一条数据

    2、后一条数据与前一条数据差值小于120,则保留上一条数据的intime,将这一条的intime当做上一条的outtime,继续往后遍历,知道遍历到最后一条数据

    3、如果后一条数据与前一条数据的差值大于120min,则将该条数据当做新的一条数据,继续循环上面的规则

代码实现:

1、将上面数据处理成为一个array,即(aaa,Array(id,intime,outtime))注:在这之前已经将每条数据中的进出时间转换为了时间戳mergedDataTmp.map(x => (x._1, .distinct.filter(x => x._2<= x._2)))
      .mapPartitions(iter => {
        iter.map(x => {
          var count = 0
          var iterNum = 0
          val tList = new ListBuffer[(String, (String, String, String))]()
          val vs = x._2.sortWith((a, b) => a._2 < b._2).toIterator
          val vsList = vs.toList
          val vsLength = vsList.length
          var tmpV = ""
          for (t <- vsList) {

            iterNum += 1
            if (count == 0) {
              tList += ((x._1, t))
              count += 1
            } else {
              val compareTime = if (!tList.isEmpty) {
                (DateUtil.dateToTimeStamp(t._2) - DateUtil.dateToTimeStamp(tList.last._2._2)) / 1000 >= 120 * 60
              } else {
                false
              }
              if (compareTime && count == 1) {
                // (如果后一条记录的进时间)-(前一条记录的进时间)>=120min
                tList.remove(tList.length - 1)
                tList += ((x._1, t))
              } else if (compareTime && count > 1) {
                // (如果后一条记录的进时间)-(前一条记录的进时间)>=120min
                val lastRecord = tList.last
                tList(tList.length - 1) = (x._1, (t._1, lastRecord._2._2, tmpV, t._3))
                tList += ((x._1, t))
                count = 1
              } else {
                // 如果后一条记录的进时间 - 前一条记录的进时间<120min
                count += 1
                if (iterNum == vsLength) {
                  val lastRecord = tList.last
                  tList(tList.length - 1) = (x._1, (t._1,lastRecord._2._2, t._3))
                }
                tmpV = t._2
              }
            }
          }
          tList
        })
      }).flatMap(x => x)

  

原文地址:https://www.cnblogs.com/Gxiaobai/p/12076583.html

时间: 2024-10-03 22:32:47

记一次逻辑代码的实现(数组内数据按照指定时间差进行分组)的相关文章

待字闺中之正数数组内和为指定数字的总数

求正数数组内和为指定数字的合并总数 比如[5, 5, 10, 2, 3] 合并值为 15 : 有4种 : (5 + 10, 5 + 10, 5 + 5 + 2 + 3, 10 + 2 + 3) 分析:有的时候,一个题目不能够立刻想到比较优化的想法,就可以先找到一个解决方案,然后根据方案的不足进行优化.而且这个时候,逆转一下思路,便会柳暗花明.由递归到动态规划,不就是如此么? 我们设定f(index,sum)表示数组从index开始到结束组成的sum的总数.那么,f(index, sum)可以表示

数组的创建/查找数组里面的内容/添加数组中元素/使用指定的字符串把数组链接起来/判断数组内是否有指定的数组元素/四种遍历进行输出数组中的元素有哪些

#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { //创建数组 //1.快速创建数组@[] NSArray*[email protected][@"month",@"tue",@" wed",@"fir"]; //2,创建空的数组 NSArray*arr=[[NSArray a

打乱数组内数据顺序

从数组最后一个数据开始和它前面的任意索引对应的数据交换 let datalist = [1, 2, 3, 4, 5, "a", "b", "c", 6, 7, 8, 9, 12, 14, 15]; function shuffle(arr) { let m = arr.length; while(m > 1) { let index = Math.floor(Math.random() * m--);//交换的索引 [arr[m], arr

js实现数组内数据的上移和下移

var swapItems = function(arr, index1, index2){ arr[index1] = arr.splice(index2,1,arr[index1])[0] return arr } var arr = [1,2,3] var newArr = [] upData (arr, index) { if (this.arr.length > 1 && index !== 0) { newArr = swapItems(arr, index, index

数组内对象根据指定属性排序

参考:https://www.jianshu.com/p/732461f2439a [arr sortUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) { BTItemModel *item1 = (BTItemModel *)obj1; BTItemModel *item2 = (BTItemModel *)obj2; return [item1.rank compare:item2.rank];

JSBinding+Bridge:逻辑代码中操作二进制数据

以这2个函数为例 class File { public static byte[] ReadAllBytes(string path); public static void WriteAllBytes(string path, byte[] data); } 如果不做特殊处理,ReadAllBytes在返回数据给Js时,是一个字节一个字节拷贝给Js的数组.这样性能是极差的.并且,大多数情况下,逻辑代码中不需要直接修改2进制数据,而只是拿着而已. 因此,不要直接使用上面的2个函数. 以下是一个

服务器主逻辑代码的重构

不知道前主程是处于什么目的,总之我接手这套程序的时候,出现了超级多的问题,也发现了超级多的问题. 比如说吧,接受网络消息逻辑是线程独立的,而发送消息给客户端缺阻塞在了逻辑线程里面:原本可以放在一个进程里面处理的逻辑,却分散在了四个进程里面去处理,导致我完成一个功能,大部分时间要话费了进程之间的玩家信息的同步上面,在我无法忍受的情况下,我终于是用NIO将网络底层从新写了,而且将四个进程合并,但是在很多逻辑上还是尽量保持了和原逻辑处理的兼容! 先说说这个重构的底层吧! 我们看下最重要的ClientH

视图封状逻辑代码及谓词查找的运用

1:封装一些优化代码 a实例:多处公用视图的相同逻辑代码处理 实例要求它的职责包括: 通过传入的 URL,加载并展示头像图片 显示一些附属信息,比如大V的标志 将用户点击头像的事件传递给外层的 View Controller 跳转到用户信息页面 @interface FDAvatarView : UIView // 假设 VIPInfo 是某个 Entity - (void)configureWithAvatarURL:(NSURL *)URL VIPInfo:(id)info tapped:(

我的手机管家(4) 进程管理逻辑代码

本节主要介绍进程管理界面的逻辑代码:至此进程管理的功能已经完善了 首先要加载正在运行的进程,获取进程信息, 这是一个耗时的操作, 所以一个子线程来处理缓冲加载, 加载完数据就通知ListView 将数据展示到 界面,listview怎么知道,数据缓冲完了,如何获取这个通知呢? 不错就是使用Thread和Handler结合,在缓冲完成后,使用handler发送一个 空消息 handler.sendEmptyMessage(1); /** * 缓冲加载进程数据 */ private void ini