Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript group objects by property [closed]

I'm trying to group objects in an array by date:

var list = [
     {
         date: "2017-01-01",
         type: "type1",
         amount: 100
     },
     {
         date: "2017-01-01",
         type: "type2",
         amount: 150
     },
     {
         date: "2017-01-02",
         type: "type1",
         amount: 200
     }
]

And I'm trying to get something like:

var dateArr = [
   {
      date: "2017-01-01",
      activities: [
        {
           type: "type1",
           amount: 100
        },
        {
           type: "type2",
           amount: 150
        }]
   }
]

I have tried a few things...like this using underscore (from here https://stackoverflow.com/a/15888912/4989305):

var dateArr = _
.chain(list)
.groupBy('date')
.map(function(value, key) {
    return {
        date: key,
        activities: [{
            type: _.pluck(value, 'type'),
            amount: _.pluck(value, 'amount')
        }]
    }
})
.value();

I've also tried this (from here https://stackoverflow.com/a/31373860/4989305)

var dateArr = {};
list.forEach(function(item){
    dateArr[item.date] = dateArr[item.date]||[];
    dateArr[item.date].push(item);
});

But, for some reason both return empty.

Any help will be greatly appreciated.

like image 226
Funktion Avatar asked Feb 27 '17 08:02

Funktion


People also ask

How to group by object property in JavaScript?

const arr = [ {food: 'apple', type: 'fruit'}, {food: 'potato', type: 'vegetable'}, {food: 'banana', type: 'fruit'}, ]; We are required to write a JavaScript function that takes in one such array. Our function should then group the array objects based on the "type" property of the objects.

How do I group an array of objects in JavaScript?

The most efficient method to group by a key on an array of objects in js is to use the reduce function. The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.

How do you iterate over an object in JavaScript?

There are two methods to iterate over an object which are discussed below: Method 1: Using for…in loop: The properties of the object can be iterated over using a for..in loop. This loop is used to iterate over all non-Symbol iterable properties of an object.

How to make group in JavaScript?

The group() method executes the callbackFn function once for each index of the array, returning a string (or value that can be coerced to a string) indicating the group of the element. A new property and array is created in the result object for each unique group name that is returned by the callback.


2 Answers

A few lines of modern JavaScript will get you the result you want:

var dateArr = Object.values(list.reduce((result, {
    date,
    type,
    amount
}) => {
    // Create new group
    if (!result[date]) result[date] = {
        date,
        activities: []
    };
    // Append to group
    result[date].activities.push({
        type,
        amount
    });
    return result;
}, {}));

Explaination:

  1. Use Array.reduce to consolidate the list into a set of results, a plain object, grouped by date.
  2. The consolidate function destructure the item into three parameters.
  3. It then creates a new group if necessary.
  4. Current item's type and amount is then pushed to the group as part of an object literal.
  5. The same set is returned to the reduce, so that the next item will consolidate into the same set.
  6. Use Object.values to extract the values from the set. (Drop the keys)
like image 71
Sheepy Avatar answered Sep 22 '22 19:09

Sheepy


You could use a hash table for groupiung by date and assign the single group to the result array.

var list = [{ date: "2017-01-01", type: "type1", amount: 100 }, { date: "2017-01-01", type: "type2", amount: 150 }, { date: "2017-01-02", type: "type1", amount: 200 }],
    result = [];

list.forEach(function (hash) {
    return function (a) {
        if (!hash[a.date]) {
            hash[a.date] = { date: a.date, activities: []};
            result.push(hash[a.date]);
        }
        hash[a.date].activities.push({ type: a.type, amount: a.amount });
    };
}(Object.create(null)));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 25
Nina Scholz Avatar answered Sep 20 '22 19:09

Nina Scholz