AngularJS - 将具有相同值的数组中的对象分组到新数组中

时间:2021-10-25 13:18:53

I have an array of objects that include a startDate. The objects are not in order of startDate. I want to create a new array and group all objects that share the same startDate into separate objects.

我有一个包含startDate的对象数组。对象不是startDate的顺序。我想创建一个新数组,并将共享相同startDate的所有对象分组到单独的对象中。

var eventArray = [
  {
    eventName: "event1",
    startDate: "2018/08/01", // YYYY/MM/DD
    id: 1
  },
  {
    eventName: "event2",
    startDate: "2018/08/03",
    id: 2
  },
  {
    eventName: "event3",
    startDate: "2018/08/01",
    id: 3
  },
  {
    eventName: "event4",
    startDate: "2018/08/06",
    id: 4
  }
];

Using angular.forEach I've tried looping through all the objects, getting the startDate value, adding that value to a new array, and adding the current object to the array where it has a matching date. I cannot find a solution to add the current event object to the object that exists in the new array (eventDays) at the index that matches my eventIndex variable.

使用angular.forEach我尝试循环遍历所有对象,获取startDate值,将该值添加到新数组,并将当前对象添加到具有匹配日期的数组。我找不到一个解决方案,将当前事件对象添加到与我的eventIndex变量匹配的索引中新数组(eventDays)中存在的对象。

let eventDays = [];
let eventIndex = 0;

angular.forEach(eventArray, function(event){
  let day = event.startDate;

  if(eventDays.length == 0){
    eventDays.push({
      dateGroup: day,
      event
    });
  }
  else {
    if(event.startDate == eventDays[eventIndex].groupDay) {
      // insert event object into eventDays[eventIndex] after dateGroup, event
    }
    else if(event.startDate !== eventDays[eventIndex].groupDay){
      eventDays.push({
        dateGroup: day,
        event
      });

      eventIndex++;
    }
  }

});

The result I'm looking for is something like this.

我正在寻找的结果是这样的。

eventDays  = [
  {
    groupDate: "2018/08/01",
    event: {
      eventName: "event1",
      startDate: "2018/08/01",
      id: 1
    },
    event: {
      eventName: "event3",
      startDate: "2018/08/01",
      id: 3
    }
  },
  {
    groupDate: "2018/08/03",
    event: {
      eventName: "event2",
      startDate: "2018/08/03",
      id: 2
    }
  },
  {
    groupDate: "2018/08/06",
    event: {
      eventName: "event4",
      startDate: "2018/08/06",
      id: 4
    }
  }
];

Is something like this possible?

这样的事情可能吗?

UPDATE

Nina is right, I cannot reuse the name keyname. I need to create another array within the object to store the objects I'm passing over. This snippet is working.

Nina是对的,我不能重用名称keyname。我需要在对象中创建另一个数组来存储我正在传递的对象。这个片段正在运行。

angular.forEach($scope.events, function (event) {

            if ($scope.eventDays.length == 0) {
                $scope.eventDays.push({
                    'groupDate': event.startDate,
                    'events': [event]
                });
            } else {
                if (event.startDate == $scope.eventDays[eventIndex].groupDate) {
                    $scope.eventDays[eventIndex].events.push(event)
                } else if (event.startDate !== $scope.eventDays[eventIndex].groupDate) {
                    $scope.eventDays.push({
                        'groupDate': event.startDate,
                        'events': [event]
                    });

                    eventIndex++;
                }
            }

        });

2 个解决方案

#1


2  

You could take a Map for grouping the same startDate and render than the array with the objects.

您可以使用Map将相同的startDate和渲染分组,而不是使用对象进行数组。

var eventArray = [{ eventName: "event1", startDate: "2018/08/01", id: 1 }, { eventName: "event2", startDate: "2018/08/03", id: 2 }, { eventName: "event3", startDate: "2018/08/01", id: 3 }, { eventName: "event4", startDate: "2018/08/06", id: 4 }],
    result = Array.from(
        eventArray.reduce((m, o) => m.set(o.startDate, (m.get(o.startDate) || []).concat(o)), new Map),
        ([groupDate, events]) => ({ groupDate, events })
    );

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

#2


1  

Nina is right, I cannot reuse the name keyname. I need to create another array within the object to store the objects I'm passing over. This snippet is working.

Nina是对的,我不能重用名称keyname。我需要在对象中创建另一个数组来存储我正在传递的对象。这个片段正在运行。

angular.forEach($scope.events, function (event) {

        if ($scope.eventDays.length == 0) {
            $scope.eventDays.push({
                'groupDate': event.startDate,
                'events': [event]
            });
        } else {
            if (event.startDate == $scope.eventDays[eventIndex].groupDate) {
                $scope.eventDays[eventIndex].events.push(event)
            } else if (event.startDate !== $scope.eventDays[eventIndex].groupDate) {
                $scope.eventDays.push({
                    'groupDate': event.startDate,
                    'events': [event]
                });

                eventIndex++;
            }
        }

    });

#1


2  

You could take a Map for grouping the same startDate and render than the array with the objects.

您可以使用Map将相同的startDate和渲染分组,而不是使用对象进行数组。

var eventArray = [{ eventName: "event1", startDate: "2018/08/01", id: 1 }, { eventName: "event2", startDate: "2018/08/03", id: 2 }, { eventName: "event3", startDate: "2018/08/01", id: 3 }, { eventName: "event4", startDate: "2018/08/06", id: 4 }],
    result = Array.from(
        eventArray.reduce((m, o) => m.set(o.startDate, (m.get(o.startDate) || []).concat(o)), new Map),
        ([groupDate, events]) => ({ groupDate, events })
    );

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

#2


1  

Nina is right, I cannot reuse the name keyname. I need to create another array within the object to store the objects I'm passing over. This snippet is working.

Nina是对的,我不能重用名称keyname。我需要在对象中创建另一个数组来存储我正在传递的对象。这个片段正在运行。

angular.forEach($scope.events, function (event) {

        if ($scope.eventDays.length == 0) {
            $scope.eventDays.push({
                'groupDate': event.startDate,
                'events': [event]
            });
        } else {
            if (event.startDate == $scope.eventDays[eventIndex].groupDate) {
                $scope.eventDays[eventIndex].events.push(event)
            } else if (event.startDate !== $scope.eventDays[eventIndex].groupDate) {
                $scope.eventDays.push({
                    'groupDate': event.startDate,
                    'events': [event]
                });

                eventIndex++;
            }
        }

    });