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

2019-11-07 08:39 来源:未知

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

TAG标签:
版权声明:本文由银河国际点击登录发布于少儿游戏下载,转载请注明出处:nodejs通过lodash合并去重由unixtime和Date组成的两个