Group values in array by two properties JavaScript


We have an array of objects like this −

const arr = [
   { value: 12, gap: 1 },
   { value: 13, gap: 1 },
   { value: 14, gap: 1 },
   { value: 15, gap: 1 },
   { value: 19, gap: 2 },
   { value: 21, gap: 1 },
   { value: 22, gap: 1 },
   { value: 23, gap: 1 },
   { value: 27, gap: 1 },
   { value: 31, gap: 4 },
   { value: 35, gap: 4 },
   { value: 39, gap: 4 },
   { value: 43, gap: 1 },
   { value: 50, gap: 1 },
   { value: 51, gap: 1 },
   { value: 52, gap: 1 },
   { value: 55, gap: 1 },
   { value: 57, gap: 1 },
];

We are required to write a function that takes in this array and returns a new array where all those consecutive objects whose value is equal to the sum of previous object’s value and gap must be grouped together in a subarray.

For example − The object with value 12 has gap 1 and its next object has value 13, so they must be grouped and with them the object with value 14 and 15, and like this.

Now, with the problem understood, let’s move on to writing the code for this problem. We will use Array.prototype.reduce() method to construct the desired array −

Example

const arr = [
   { value: 12, gap: 1 },
   { value: 13, gap: 1 },
   { value: 14, gap: 1 },
   { value: 15, gap: 1 },
   { value: 19, gap: 2 },
   { value: 21, gap: 1 },
   { value: 22, gap: 1 },
   { value: 23, gap: 1 },
   { value: 27, gap: 1 },
   { value: 31, gap: 4 },
   { value: 35, gap: 4 },
   { value: 39, gap: 4 },
   { value: 43, gap: 1 },
   { value: 50, gap: 1 },
   { value: 51, gap: 1 },
   { value: 52, gap: 1 },
   { value: 55, gap: 1 },
   { value: 57, gap: 1 },
];
const groupArray = arr => {
   return arr.reduce((acc, val, ind, array) => {
      // the accumulated data and lastIndex of accumulated data
      const { data, currentIndex } = acc;
      // the current object properties
      const { value, gap } = val;
      // the previous object properties
      const v = arr[ind-1]?.value;
      const g = arr[ind-1]?.gap;
      if(ind === 0 || value !== v + g){
         // recording the index of last object and pushing new subarray
         const index = data.push([val]) - 1;
         return { data, currentIndex: index };
      };
      data[currentIndex].push(val);
      return { data, currentIndex };
   }, {
      data: [],
      currentIndex: 0
   }).data;
}
console.log(groupArray(arr));

Output

The output in the console will be −

[
   [
      { value: 12, gap: 1 },
      { value: 13, gap: 1 },
      { value: 14, gap: 1 },
      { value: 15, gap: 1 }
   ],
   [
      { value: 19, gap: 2 },
      { value: 21, gap: 1 },
      { value: 22, gap: 1 },
      { value: 23, gap: 1 }
   ],
   [ { value: 27, gap: 1 } ],
   [
      { value: 31, gap: 4 },
      { value: 35, gap: 4 },
      { value: 39, gap: 4 },
      { value: 43, gap: 1 }
   ],
   [
      { value: 50, gap: 1 },
      { value: 51, gap: 1 },
      { value: 52, gap: 1 }
   ],
      [ { value: 55, gap: 1 } ],
      [ { value: 57, gap: 1 } ]
]

Updated on: 25-Aug-2020

826 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements