如何比较对象数组中每个对象组中的时间属性

时间:2018-07-23 07:58:56

标签: javascript arrays data-structures filter reduce

我确实有一个对象数组,每个对象组都需要根据其时间属性进行过滤,并且在输出中,它仅应返回时差小于1分钟的卷边,并删除时差大于1分钟的卷边。时差(采用相同格式并分组)。

更新:每个连续事务之间的时间差应小于1分钟。

var grouped = [
[
    {"id":29,"sourceAccount":"my_account","targetAccount":"cinema","amount":-580,"category":"other","time":"2018-05-05T20:01:18.000Z"},
    {"id":18,"sourceAccount":"my_account","targetAccount":"cinema","amount":-580,"category":"other","time":"2018-04-05T20:01:18.000Z"}
],
[
    {"id":38,"sourceAccount":"my_account","targetAccount":"restaurant","amount":-970,"category":"eating_out","time":"2018-05-17T19:52:46.000Z"},
    {"id":22,"sourceAccount":"my_account","targetAccount":"restaurant","amount":-970,"category":"eating_out","time":"2018-04-17T19:52:46.000Z"}
],
[
    {"id":31,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:55:10.000Z"},
    {"id":30,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:54:21.000Z"},
    {"id":33,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:57:05.000Z"},
    {"id":19,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-04-07T09:54:21.000Z"},
    {"id":32,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:56:09.000Z"},
    {"id":35,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:58:06.000Z"}
],
[
    {"id":14,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-04-01T10:24:40.000Z"},
    {"id":15,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-04-01T10:25:10.000Z"},
    {"id":13,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-04-01T10:24:00.000Z"},
    {"id":9,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-03-04T07:14:20.000Z"},
    {"id":2,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-03-01T12:34:00.000Z"},
    {"id":5,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-03-02T09:25:20.000Z"}
],
[
    {"id":39,"sourceAccount":"my_account","targetAccount":"fitness_club","amount":-610,"category":"other","time":"2018-05-22T11:54:10.000Z"},
    {"id":24,"sourceAccount":"my_account","targetAccount":"fitness_club","amount":-610,"category":"other","time":"2018-04-22T11:54:10.000Z"}
],
[
    {"id":41,"sourceAccount":"my_account","targetAccount":"cinema","amount":-450,"category":"other","time":"2018-05-23T19:13:10.000Z"},
    {"id":26,"sourceAccount":"my_account","targetAccount":"cinema","amount":-450,"category":"other","time":"2018-04-23T19:13:10.000Z"}
],
[
    {"id":1,"sourceAccount":"company_x","targetAccount":"my_account","amount":10000,"category":"salary","time":"2018-02-25T08:00:00.000Z"},
    {"id":27,"sourceAccount":"company_x","targetAccount":"my_account","amount":10000,"category":"salary","time":"2018-04-25T08:00:00.000Z"},
    {"id":16,"sourceAccount":"company_x","targetAccount":"my_account","amount":10000,"category":"salary","time":"2018-03-25T08:10:00.000Z"}
],
[
    {"id":20,"sourceAccount":"my_account","targetAccount":"internet_shop","amount":-1650,"category":"other","time":"2018-04-08T21:36:41.000Z"},
    {"id":36,"sourceAccount":"my_account","targetAccount":"internet_shop","amount":-1650,"category":"other","time":"2018-05-08T21:36:41.000Z"}
],
[
    {"id":39,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-70,"category":"eating_out","time":"2018-05-15T09:12:20.000Z"},
    {"id":23,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-70,"category":"eating_out","time":"2018-04-15T09:12:20.000Z"}
],
[
    {"id":40,"sourceAccount":"my_account","targetAccount":"supermarket","amount":-850,"category":"groceries","time":"2018-05-20T18:51:31.000Z"},
    {"id":25,"sourceAccount":"my_account","targetAccount":"supermarket","amount":-850,"category":"groceries","time":"2018-04-20T18:51:31.000Z"}
],
[
    {"id":17,"sourceAccount":"my_account","targetAccount":"supermarket","amount":-1870,"category":"groceries","time":"2018-04-05T10:24:30.000Z"},
    {"id":28,"sourceAccount":"my_account","targetAccount":"supermarket","amount":-1870,"category":"groceries","time":"2018-05-05T10:24:30.000Z"}
],
[
    {"id":21,"sourceAccount":"my_account","targetAccount":"supermarket","amount":-1690,"category":"groceries","time":"2018-04-10T18:14:10.000Z"},
    {"id":37,"sourceAccount":"my_account","targetAccount":"supermarket","amount":-1690,"category":"groceries","time":"2018-05-10T18:14:10.000Z"}
  ]
]

这是我尝试过的方法,但是此项目中仍有超过1分钟的项目(甚至有些项目的时差超过1个月!)

var result = grouped.map((tr, i) => {
        return tr.filter((t, j) => {
          if (grouped[i][j - 1]) {
            var d1 = Date.parse(t.time);
            var d2 = Date.parse(grouped[i][j - 1].time);
            return (d1 - d2) <= 60000;
          }
          return true;
        });
      });

在运行上面的代码之前,我按时间对它进行排序,如下所示:

  grouped.sort(function (a, b) {
        return b.time > a.time
    });

更新:

给定对象组的预期输出应该是这样的:

var expectedOutput = [
[
    {"id":31,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:55:10.000Z"},
    {"id":30,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:54:21.000Z"},
    {"id":32,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:56:09.000Z"}
],
[
    {"id":14,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-04-01T10:24:40.000Z"},
    {"id":15,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-04-01T10:25:10.000Z"},
    {"id":13,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-04-01T10:24:00.000Z"}
]
]

真的不确定我做错了什么,有人可以帮我吗?谢谢

2 个答案:

答案 0 :(得分:1)

使用给定的数据结构,方法需要两次reduce一个列表。首先,将帐户项目列表分组的外部列表结构。首先,每个列表都应按其帐户项目的时间戳(时间属性)进行排序。第二步是简化步骤,通过比较当前项目与其上一个和下一个同级项目(如果有)之间的时间偏移,来找到项目的有效范围。仅收集(严格)有效范围内的项目。

var grouped = [[
 {"id":29,"sourceAccount":"my_account","targetAccount":"cinema","amount":-580,"category":"other","time":"2018-05-05T20:01:18.000Z"},
 {"id":18,"sourceAccount":"my_account","targetAccount":"cinema","amount":-580,"category":"other","time":"2018-04-05T20:01:18.000Z"}
], [
 {"id":38,"sourceAccount":"my_account","targetAccount":"restaurant","amount":-970,"category":"eating_out","time":"2018-05-17T19:52:46.000Z"},
 {"id":22,"sourceAccount":"my_account","targetAccount":"restaurant","amount":-970,"category":"eating_out","time":"2018-04-17T19:52:46.000Z"}
], [
 {"id":31,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:55:10.000Z"},
 {"id":30,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:54:21.000Z"},
 {"id":33,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:57:05.000Z"},
 {"id":19,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-04-07T09:54:21.000Z"},
 {"id":32,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:56:09.000Z"},
 {"id":35,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-90,"category":"eating_out","time":"2018-05-07T09:58:06.000Z"}
], [
 {"id":14,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-04-01T10:24:40.000Z"},
 {"id":15,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-04-01T10:25:10.000Z"},
 {"id":13,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-04-01T10:24:00.000Z"},
 {"id":9,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-03-04T07:14:20.000Z"},
 {"id":2,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-03-01T12:34:00.000Z"},
 {"id":5,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-50,"category":"eating_out","time":"2018-03-02T09:25:20.000Z"}
], [
 {"id":39,"sourceAccount":"my_account","targetAccount":"fitness_club","amount":-610,"category":"other","time":"2018-05-22T11:54:10.000Z"},
 {"id":24,"sourceAccount":"my_account","targetAccount":"fitness_club","amount":-610,"category":"other","time":"2018-04-22T11:54:10.000Z"}
], [
 {"id":41,"sourceAccount":"my_account","targetAccount":"cinema","amount":-450,"category":"other","time":"2018-05-23T19:13:10.000Z"},
 {"id":26,"sourceAccount":"my_account","targetAccount":"cinema","amount":-450,"category":"other","time":"2018-04-23T19:13:10.000Z"}
], [
 {"id":1,"sourceAccount":"company_x","targetAccount":"my_account","amount":10000,"category":"salary","time":"2018-02-25T08:00:00.000Z"},
 {"id":27,"sourceAccount":"company_x","targetAccount":"my_account","amount":10000,"category":"salary","time":"2018-04-25T08:00:00.000Z"},
 {"id":16,"sourceAccount":"company_x","targetAccount":"my_account","amount":10000,"category":"salary","time":"2018-03-25T08:10:00.000Z"}
], [
 {"id":20,"sourceAccount":"my_account","targetAccount":"internet_shop","amount":-1650,"category":"other","time":"2018-04-08T21:36:41.000Z"},
 {"id":36,"sourceAccount":"my_account","targetAccount":"internet_shop","amount":-1650,"category":"other","time":"2018-05-08T21:36:41.000Z"}
], [
 {"id":39,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-70,"category":"eating_out","time":"2018-05-15T09:12:20.000Z"},
 {"id":23,"sourceAccount":"my_account","targetAccount":"coffee_shop","amount":-70,"category":"eating_out","time":"2018-04-15T09:12:20.000Z"}
], [
 {"id":40,"sourceAccount":"my_account","targetAccount":"supermarket","amount":-850,"category":"groceries","time":"2018-05-20T18:51:31.000Z"},
 {"id":25,"sourceAccount":"my_account","targetAccount":"supermarket","amount":-850,"category":"groceries","time":"2018-04-20T18:51:31.000Z"}
], [
 {"id":17,"sourceAccount":"my_account","targetAccount":"supermarket","amount":-1870,"category":"groceries","time":"2018-04-05T10:24:30.000Z"},
 {"id":28,"sourceAccount":"my_account","targetAccount":"supermarket","amount":-1870,"category":"groceries","time":"2018-05-05T10:24:30.000Z"}
], [
 {"id":21,"sourceAccount":"my_account","targetAccount":"supermarket","amount":-1690,"category":"groceries","time":"2018-04-10T18:14:10.000Z"},
 {"id":37,"sourceAccount":"my_account","targetAccount":"supermarket","amount":-1690,"category":"groceries","time":"2018-05-10T18:14:10.000Z"}
]];

function orderByTimeProperty(a, b) {
  return ((a.time < b.time && -1) || (a.time > b.time && 1) || 0);
}

function collectListItemsWithLessThanOneMinuteDelta(collector, item, idx, list) {
  function isValidTimeDelta(a, b) {
    return (Math.abs((new Date(b)).getTime() - (new Date(a)).getTime()) < timeDelta);
  }
  var
    timeDelta = (1000 * 60),
    prevItem  = list[idx - 1],
    nextItem  = list[idx + 1];
  if (
    (prevItem && nextItem && isValidTimeDelta(prevItem.time, item.time) && isValidTimeDelta(item.time, nextItem.time))
    || (nextItem && isValidTimeDelta(item.time, nextItem.time))
    || (prevItem && isValidTimeDelta(prevItem.time, item.time))
  ) {
    collector.push(item);
  }
  return collector;
}

function collectGroupedListItemsWithLessThanOneMinuteDelta(collector, list) {
  list = list.sort(orderByTimeProperty).reduce(collectListItemsWithLessThanOneMinuteDelta, []);

  if (list.length >= 1) {
    collector.push(list);
  }
  return collector;
}

var list = grouped.reduce(collectGroupedListItemsWithLessThanOneMinuteDelta, []);

console.log('reduced list : ', list);
.as-console-wrapper { max-height: 100%!important; top: 0; }

答案 1 :(得分:0)

$\1
$$$1
  

输出::

let newArr = [];
grouped.forEach(function(elements){
    let res = compareTime(elements)
    if(res.length > 0)
    newArr.push(res)
})
console.log(newArr)

function compareTime(value) {
    let newArr = []
    let existCheck = []
    for(let i = 0; i < value.length; i ++) {
        let iTime = Date.parse(value[i].time)
        for(let j=i + 1; j < value.length; j++) {
            let jTime = Date.parse(value[j].time)
            let timeCompare = iTime - jTime 
            if(timeCompare < 60000 && timeCompare > -60000){
                if(!existCheck.includes(value[i].time)) {
                    newArr.push(value[i])
                    existCheck.push(value[i].time)
                }
                if(!existCheck.includes(value[j].time)) {
                    newArr.push(value[j])
                    existCheck.push(value[j].time)
                }
            }
        }
    }
    return newArr
}