快捷搜索:
当前位置: 银河手机版app > 幼儿园游戏大全 > 正文

nodejs通过lodash合并去重由unixtime和Date组成的两个

时间:2019-11-03 17:14来源:幼儿园游戏大全
1. 标题来自 近年在得以达成二个API,此中有大器晚成都部队分效应是亟需从Mongodb中抽取三个由Date对象组成的数组,然后将顾客端传过来的unixtime合併到该数组中,并且去重新。 举个例

1. 标题来自


近年在得以达成二个API,此中有大器晚成都部队分效应是亟需从Mongodb中抽取三个由Date对象组成的数组,然后将顾客端传过来的unixtime合併到该数组中,并且去重新。

举个例子,即便从mongodb中取回来的数额中有三个名称叫gaming的项,特地用来记录顾客步入游戏的发端时间和退出时间。 那么mongoose的schema的概念将轮廓是这么的:

const DeviceLogSchema = new Schema({
 ...
  gaming: [{ enter: Date, exit: Date, _id: false }],          
 ... 
});

而从mongodb取回来的数额大概就是那一个样子的:

{
"gaming": [
      {
        "enter": 2017-04-25T14:32:12.081Z,
        "exit": 2017-04-25T14:48:52.082Z,
      },
      {
        "enter": 2017-04-26T14:32:12.081Z,
        "exit": 2017-04-26T14:48:52.082Z,
      }
    ],
}

也正是说通过mongoose的model取回来的记录中,enter和exit都以Date(对mongodb来讲)类型的,而对此js来讲,正是三个Object(js将有着轻易类型以外的数据类型都管理成Object)。

let deviceLog = await DeviceLog.findOne({});
console.log(typeof deviceLog.enter) // ->Object

而客商端每间隔意气风发段时间就能调用api来将新的客户游戏时间回传给服务器,但用的格式是unixtime。

{
    "gaming": [{
      "enter": 1493130733081,
      "exit": 1493131734082,
    },{
      "enter": 1493130735084,
      "exit": 1493131736087,
    }],
}

此处的enter和exit的unixtime时间格式,对于js来讲,正是number类型的。

咱俩因而mongoose来保存的时候,无需将unixtime举行任何转变,直接保存, mongoose会将其机动转成Date格式举行封存。也等于说,借使保留前的gaming内容是之类这么些样子的:

"gaming": [
      {
        "enter": 2017-04-25T14:32:12.081Z,
        "exit": 2017-04-25T14:48:52.082Z,
      },
      {
        "enter": 2017-04-26T14:32:12.081Z,
        "exit": 2017-04-26T14:48:52.082Z,
      },
      {
        "enter": 1493130733081,
        "exit": 1493131734082,
      },
      {
        "enter": 1493130735084,
        "exit": 1493131736087,
      }
    ],

那么通过mongoose的model保存之后,最后会自动产生近乎以下那样的格式:

"gaming": [
      {
        "enter": 2017-04-25T14:32:12.081Z,
        "exit": 2017-04-25T14:48:52.082Z,
      },
      {
        "enter": 2017-04-26T14:32:12.081Z,
        "exit": 2017-04-26T14:48:52.082Z,
      },
      {
        "enter": 2017-04-27T14:22:12.021Z,
        "exit": 2017-04-27T15:32:12.031Z,
      },
      {
        "enter": 2017-04-26T16:22:12.082Z,
        "exit": 2017-04-26T16:52:12.082Z,
      }
    ],

那正是说这里要解决的标题正是:

  • 如何将顾客端传过来的新数组和从mongodb取回来的数组进行联合
  • 统有的时候怎样依据游戏步向的岁月enter来去重复

不可否认,我们得以用原本的主意,做两层遍历,分别便利八个不相同的数组,然后将中间一个比对数据的类型转变来别的三个多少对应的品类,然后开展相比其是还是不是等于,相等的话就去掉,不想等的话就将数据追加到数组中。

但,那样功效太低了,应该有越来越好的越来越高雅的主意来援助大家管理这种难点。

2. 实验数据

那么我们就依赖地点碰着的标题,来确立多个实验所用的多寡。三个是象征从mongodb取回来的数据:

const orgGaming = [
      {
        "enter": new Date("2017-04-25T14:32:12.081Z"),
        "exit": new Date("2017-04-25T14:48:52.082Z"),
      },
      {
        "enter": new Date("2017-04-26T14:32:12.081Z"),
        "exit": new Date("2017-04-26T14:48:52.082Z"),
      }
]

三个是客商端传进来的数码:

const newGaming = [
     {
        "enter": 1493130732081, // 这和orgGamine第一条数据重复
        "exit": 1493131732082, // 这和orgGamine第一条数据重复
      },
      {
        "enter": 1493130735084,
        "exit": 1493131736087,
      }
    ]

新数组中的第一条数据和enter和数据库中的第一条数据的enter,事实上是如出生龙活虎辙的,所以大家目的在于统一之后那一个重复数据是去掉的。

3. ES6数结缘并新特色


骨子里,假若不是因为要思忖去重新的标题来讲,大家一起能够通过ES6的新特征来完毕的。

array1.push(...array2)

此处的'...'操作符叫做扩充运算符,是ES6引进的新特点。指标是将三个数组压垮成用逗号分隔的参数体系。

const array = [1, 2];
console.log(...array); // 相当于 console.log(1,2)

据此地点的亲自过问代码的情趣正是将array2打垮后,将每一个成分作为参数push到array第11中学变化新的数组。所以,若是采取到大家的情况中的话

const orgGaming = [
      {
        "enter": new Date("2017-04-25T14:32:12.081Z"),
        "exit": new Date("2017-04-25T14:48:52.082Z"),
      },
      {
        "enter": new Date("2017-04-26T14:32:12.081Z"),
        "exit": new Date("2017-04-26T14:48:52.082Z"),
      }
]

const newGaming = [
     {
        "enter": 1493130732081,
        "exit": 1493131732082,
      },
      {
        "enter": 1493130735084,
        "exit": 1493131736087,
      }
]

orgGaming.push(...newGaming);
console.log(orgGaming);

终极将会输出未有去重新的结果:

[ 
  { enter: 2017-04-25T14:32:12.081Z,
    exit: 2017-04-25T14:48:52.082Z },
  { enter: 2017-04-26T14:32:12.081Z,
    exit: 2017-04-26T14:48:52.082Z },
  { enter: 1493130732081, 
    exit: 1493131732082 },
  { enter: 1493130735084, 
    exit: 1493131736087 } 
]

理当如此,ES6的那一个数组归总情势仍然是能够这么写:

[...array1,...array2]

还要,ES6还提供了对简易数据类型去重新形式:

[...new Set([...array1 ,...array2])];

不过,那一个只可以针对轻巧数据类型实行去重新,比方数字类型和字串类型等。

const array1 = ['techgogogo', 'sina', 'baidu'];
const array2 = ['techgogogo', 'google'];
console.log([... new Set([...array1, ...array2])]);

终极输出:

[ 'techgogogo', 'sina', 'baidu', 'google' ]

而是对于大家那边的靶子类型组成的数组,它是做不到的。

最根本的是,它从不提供叁个comparator的回调方法来放大家管理相应怎么着推断,四个数据是不是是重复的。

此地,lodash的数组操作,恐怕是个不利的实施方案(之后生可畏卡塔尔。

4. lodash统少年老成对象类型数组并去重新

lodash的unionWith方式得以统少年老成三个数组,并且能够让大家提供二个comparator方法来支配该如何比超多个数组中的成分是或不是是后生可畏致的,以此来推断这些数额是不是是重复的。

合俄语档对unionWith方法的陈述请看这里:https://lodash.com/docs/4.17.4#unionWith

_.unionWith([arrays], [comparator])

明白起来也比较轻易,请看代码如下:

const _ = require('lodash');
const orgGaming = [
      {
        "enter": new Date("2017-04-25T14:32:12.081Z"),
        "exit": new Date("2017-04-25T14:48:52.082Z"),
      },
      {
        "enter": new Date("2017-04-26T14:32:12.081Z"),
        "exit": new Date("2017-04-26T14:48:52.082Z"),
      }
]

const newGaming = [
     {
        "enter": 1493130732081,
        "exit": 1493131732082,
      },
      {
        "enter": 1493130735084,
        "exit": 1493131736087,
      }
]

gaming = _.unionWith(orgGaming, newGaming, (value1, value2) => {
    if (typeof value1.enter === 'number' && typeof value2.enter === 'number') {
        return (value1.enter === value2.enter);
    } else if (typeof value1.enter === 'number' && typeof value2.enter === 'object') {
        return (value1.enter === value2.enter.getTime());
    } else if (typeof value1.enter === 'object' && typeof value2.enter === 'number') {
        return (value1.enter.getTime() === value2.enter);
    } else if (typeof value1.enter === 'object' && typeof value2.enter === 'object') {
        return (value1.enter.getTime() === value2.enter.getTime());
    }
});

console.log(gaming);

此处首要的地点就是uionWith,有几个地方须求在乎:

  • 参数的豆蔻年华大器晚成,非常是前三个数组参数。假使第一个数组中某些成员判断和第四个数组中的某些成员是重新的,那么首先个数组中的该因素会保留,首个数组中的对应成分会移除。
  • 其三个参数就是叁个回调方法,采纳八个参数,其实正是多个需求比没错数组的积极分子,这里大家经过比对七个成员的enter是不是等于来决断该成员是不是再度。
  • 认清是还是不是再度的时候,我们必要将日志先转变来unixtime的格式,然后再进行相比较。

最终我们得以看出去重新后的输出:

[ { enter: 2017-04-25T14:32:12.081Z,
    exit: 2017-04-25T14:48:52.082Z },
  { enter: 2017-04-26T14:32:12.081Z,
    exit: 2017-04-26T14:48:52.082Z },
  { enter: 1493130735084, 
    exit: 1493131736087 } ]

能够见见,最后输出的列表中独有多个对象,在这之中三个再一次的早就被裁撤掉了。

谈到底大家透过mongoose将这份数据存款和储蓄到mongodb时,如前方所述,会自动将unixtime转变来Date进行仓储,那样数据就能够集起来了。这里mongoose的操作就不赘述了,有意思味的意中人可以团结奉行下。

上述正是作者对八个由对象类型组成的数组进行合併的有些尝试和施行,就算大家有越来越好更温婉的方法的话,招待在商议中给出去。先拜谢了!

正文由世界会黄冈分舵编写,转发需授权,喜欢点个赞,嘲谑请商量,进一层交换请关怀民众号techgogogo恐怕直接关联本身Wechatzhubaitian1

编辑:幼儿园游戏大全 本文来源:nodejs通过lodash合并去重由unixtime和Date组成的两个

关键词: