如何根据对象的属性对对象数组进行分组

时间:2019-08-14 17:12:50

标签: javascript arrays ecmascript-6

我有一系列这样的对象

[
{
        id: 536,
        user_id: 87,
        event_type: 'CA',
        purpose: 1,
        timestamp: 1435678384
      },
      {
        id: 5368,
        user_id: 87,
        event_type: 'CA',
        purpose: 4,
        timestamp: 1435678384
      },
      {
        id: 53688,
        user_id: 87,
        event_type: 'CA',
        purpose: 9,
        timestamp: 1435678385
      },
      {
        id: 588,
        user_id: 87,
        event_type: 'CA',
        purpose: 7,
        timestamp: 1435678386
      },
      {
        id: 588,
        user_id: 87,
        event_type: 'CA',
        purpose: 5,
        timestamp: 1435678396
      },
      {
        id: 588,
        user_id: 87,
        event_type: 'CA',
        purpose: 8,
        timestamp: 1435678397
      },
      {
        id: 588,
        user_id: 87,
        event_type: 'CA',
        purpose: 2,
        timestamp: 1435678398
      },
      {
        id: 588,
        user_id: 87,
        event_type: 'CA',
        purpose: 3,
        timestamp: 1435678350
      }
]

我想按它们的 timestamp 对数组中的所有对象进行分组,因此,如果对象中的时间戳位于彼此之间5ms之内,则将这些对象组合成一个单独的数组

所以在这种情况下,我希望输出看起来像

[
    [{
            id: 536,
            user_id: 87,
            event_type: 'CA',
            purpose: 1,
            timestamp: 1435678384
        },
        {
            id: 5368,
            user_id: 87,
            event_type: 'CA',
            purpose: 4,
            timestamp: 1435678384
        },
        {
            id: 53688,
            user_id: 87,
            event_type: 'CA',
            purpose: 9,
            timestamp: 1435678385
        },
        {
            id: 588,
            user_id: 87,
            event_type: 'CA',
            purpose: 7,
            timestamp: 1435678386
        }
    ],
    [{
            id: 588,
            user_id: 87,
            event_type: 'CA',
            purpose: 5,
            timestamp: 1435678396
        },
        {
            id: 588,
            user_id: 87,
            event_type: 'CA',
            purpose: 8,
            timestamp: 1435678397
        },
        {
            id: 588,
            user_id: 87,
            event_type: 'CA',
            purpose: 2,
            timestamp: 1435678398
        }
    ], {
        id: 588,
        user_id: 87,
        event_type: 'CA',
        purpose: 3,
        timestamp: 1435678350
    }
]

我尝试对此使用数组方法过滤器以获取所需的代码。但是,我只能隔离一个组,而不能拥有这样的2D数组。请注意,最后一个无法分组的对象(时间戳远远超过任何其他对象的时间戳的5ms)不在数组中。

到目前为止,我的努力并不多,这是我尝试过的

ca.forEach((cur, index) => {
            let newArr = []
            let grouped = ca.filter((target, innerIndex) => {
                    if ((cur.timestamp - target.timestamp) < 5) {
                    return true
                } else {
                    return false
                }
            })

任何解决此问题的帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

您可以尝试使用reduce函数:see here my code in stackblitz

var firstArray = [
{
        id: 536,
        user_id: 87,
        event_type: 'CA',
        purpose: 1,
        timestamp: 1435678384
      },
      {
        id: 5368,
        user_id: 87,
        event_type: 'CA',
        purpose: 4,
        timestamp: 1435678384
      },
      {
        id: 53688,
        user_id: 87,
        event_type: 'CA',
        purpose: 9,
        timestamp: 1435678385
      },
      {
        id: 588,
        user_id: 87,
        event_type: 'CA',
        purpose: 7,
        timestamp: 1435678386
      },
      {
        id: 588,
        user_id: 87,
        event_type: 'CA',
        purpose: 5,
        timestamp: 1435678396
      },
      {
        id: 588,
        user_id: 87,
        event_type: 'CA',
        purpose: 8,
        timestamp: 1435678397
      },
      {
        id: 588,
        user_id: 87,
        event_type: 'CA',
        purpose: 2,
        timestamp: 1435678398
      },
      {
        id: 588,
        user_id: 87,
        event_type: 'CA',
        purpose: 3,
        timestamp: 1435678350
      }
];

var secondArray = firstArray.sort((a, b)=>{
    return a.timestamp-b.timestamp
}).reduce(
  (accumulator,current)=>{
    if(
      typeof accumulator[accumulator.length-1]==='object' &&
      current.timestamp - accumulator[accumulator.length-1][0].timestamp <5
    ) {
      accumulator[accumulator.length-1].push(current);
    } else {
      accumulator.push([current]);
    }
    return accumulator;
  },
  []
);


console.log(secondArray);

编辑:我没有看到5毫秒的需求,但是您可以调整if使其适合您的需求,并告诉我是否要我这样做。 ;)

EDIT2:我添加了sort函数以便按时间戳进行排序,例如,我们确定减号运算的顺序正确,并且我对reduce的if进行了减号运算。让我知道是否有帮助

答案 1 :(得分:0)

您可以创建一个大数组。还有一个小的可重用数组,您可以放置​​所有相关的对象,然后将tempArray推入allArray Array并清除它,然后对所有其他对象执行相同的操作。使用数组的foreach方法获取具有该特定属性的所有对象。

让allArray = [];

让tempArray = [];

allArray.push(tempArray);