God of all wars
God of all wars

Reputation: 80

How to group an array of objects in javascript?

I'm trying to group an array of objects. The array should be grouped following this quote:

Group by type respecting the sequence.

Array I wish to group

var arrayObj = [
    { "type": "user", "text": "user1" },
    { "type": "user", "text": "user2" },
    { "type": "user", "text": "user3" },
    { "type": "clerk", "text": "clerk1" },
    { "type": "user", "text": "user4" },
    { "type": "clerk", "text": "clerk2" },
    { "type": "clerk", "text": "clerk3" },
    { "type": "user", "text": "user5" },
    { "type": "user", "text": "user6" }
];

The way I want it to be grouped:

var newArray = [
  [
      {type: "user", text: "user1"},
      {type: "user", text: "user2"},
      {type: "user", text: "user3"}
  ],
  
  [
      {type: "clerk", text: "clerk1"}
  ],
  
  [
      {type: "user", text: "user4"}
  ],
  
  [
      {type: "clerk", text: "clerk2"},
      {type: "clerk", text: "clerk3"}
  ],  
    
  [
      {type: "user", text: "user5"},
      {type: "user", text: "user6"} 
  ]
];

What i tried:

I'm trying to use a filter, but without success since it even groups, but it groups all that are of the same type without respecting the sequence I want (from the array above);

var arrayObj = [
    { "type": "user", "text": "user1" },
    { "type": "user", "text": "user2" },
    { "type": "user", "text": "user3" },
    { "type": "clerk", "text": "clerk1" },
    { "type": "user", "text": "user4" },
    { "type": "clerk", "text": "clerk2" },
    { "type": "clerk", "text": "clerk3" },
    { "type": "user", "text": "user5" },
    { "type": "user", "text": "user6" }
];

var newArray = [];

newArray.push(filtrarArray(arrayObj, 'clerk'));
newArray.push(filtrarArray(arrayObj, 'user'));

console.log(newArray);

function filtrarArray(array, type) {
    return array.filter(function (val) {
        return val.type === type;
    });
} 

Upvotes: 0

Views: 333

Answers (5)

God of all wars
God of all wars

Reputation: 80

I'm responding with another way I found to solve my problem. This is just one more way I decided to comment.

Let's go:
I'm traversing the arrayObjects array using the appropriate loop for arrays for...of and then checking if the variable I set for arrayObjects (loopArrObj) has a different value of type of the variable (typeValue), if it is inserted at the end of the new array (grouping) using the array method push an empty array and then assign the value of the loopArrObj(Ie, there will be in the array grouping array empty only for the values ​​that are different).

So far so good, we have the first empty array. Next I'm defining this empty array with the push method the loopArrObj object in question, then we get the value through the console. I'm removing 1 from grouping.lengh so the loop assigns from 0 and not 1.

var arrayObjects = [
    { "type": "user", "text": "user1" },
    { "type": "user", "text": "user2" },
    { "type": "user", "text": "user3" },
    { "type": "clerk", "text": "clerk1" },
    { "type": "user", "text": "user4" },
    { "type": "clerk", "text": "clerk2" },
    { "type": "clerk", "text": "clerk3" },
    { "type": "user", "text": "user5" },
    { "type": "user", "text": "user6" }
];

let typeValue,
    grouping = [],
    loopArrObj;

for (loopArrObj of arrayObjects) {

    if (loopArrObj.type !== typeValue) {
        grouping.push([]); 
        typeValue = loopArrObj.type;
    }

    grouping[grouping.length - 1].push(loopArrObj);
}

console.log(grouping);

Upvotes: 0

user15889308
user15889308

Reputation:

See This solution it will work

var arrayObj = [
  { type: "user", text: "user1" },
  { type: "user", text: "user2" },
  { type: "user", text: "user3" },
  { type: "clerk", text: "clerk1" },
  { type: "user", text: "user4" },
  { type: "clerk", text: "clerk2" },
  { type: "clerk", text: "clerk3" },
  { type: "user", text: "user5" },
  { type: "user", text: "user6" },
];

let typeNow = arrayObj[0].type;

let res = [];
let resultArray = [];
arrayObj.forEach((obj, i) => {
  if (obj.type == typeNow) {
    resultArray.push(obj);
  } else {
    resultArray = [obj];
    res.push(resultArray);
    typeNow = obj.type;
  }
  if (i == arrayObj.length - 1) res.push(resultArray);
});
console.log(res);

This is best solution can i have

It seem unordred because of Browser auto order but if you try in js file it will work and ordred

Upvotes: 1

Dmitry Kostyuk
Dmitry Kostyuk

Reputation: 1459

The snippet below first sorts the array by type, which then makes it easy to loop through and group. Let me know if this solves your problem :)

EDIT

Just realized you didn't need sorting, so I commented the sort function out, but it's always there to be uncommented if you change your mind :)

const arrayObj = [
  { type: 'user', text: 'user1' },
  { type: 'user', text: 'user2' },
  { type: 'user', text: 'user3' },
  { type: 'clerk', text: 'clerk1' },
  { type: 'user', text: 'user4' },
  { type: 'clerk', text: 'clerk2' },
  { type: 'clerk', text: 'clerk3' },
  { type: 'user', text: 'user5' },
  { type: 'user', text: 'user6' },
];

const group = ar =>
  ar
    // .sort((a, b) => (a.type < b.type ? -1 : 1))
    .reduce((newAr, obj, i) => {
      if (0 === i) return [[obj]];
      if (obj.type === newAr[newAr.length - 1][0].type)
        return newAr[newAr.length - 1].push(obj), newAr;
      return [...newAr, [obj]];
    }, []);

const groupedAr = group(arrayObj);
console.log(groupedAr);

Upvotes: 2

daremachine
daremachine

Reputation: 2788

This is probably not best pure solution but works as you need.

var arrayObj = [
    { "type": "user", "text": "user1" },
    { "type": "user", "text": "user2" },
    { "type": "user", "text": "user3" },
    { "type": "clerk", "text": "clerk1" },
    { "type": "user", "text": "user4" },
    { "type": "clerk", "text": "clerk2" },
    { "type": "clerk", "text": "clerk3" },
    { "type": "user", "text": "user5" },
    { "type": "user", "text": "user6" }
];

let lastType;
let arr = [];
let arrIndex = -1;

arrayObj.forEach(obj => {
  if(obj.type == lastType) { // add item into last group array by index
    arr[arrIndex].push(obj);
  }
  else { // or add new group array
    lastType = obj.type;
    arrIndex++;
    arr.push([obj]);
  }
})

console.log(arr);

Upvotes: 1

Chira Codrin-Mihai
Chira Codrin-Mihai

Reputation: 66

function groupConsecutive(arrayObj) {
    if (arrayObj.length === 0) {
        return [];
    }

    let matchedTypesIndex = 0;
    let newArray = [
        [
             arrayObj[0]
        ]
    ];

    let currentType = arrayObj[0]["type"];
    let i = 1;

    while (i < arrayObj.length) {
        if (arrayObj[i]["type"] === currentType) {
            newArray[matchedTypesIndex].push(arrayObj[i]);
        } else {
            currentType = arrayObj[i]["type"];
            newArray.push([]);
            matchedTypesIndex++;
            newArray[matchedTypesIndex].push(arrayObj[i]);
        }

        i++;
    }

    return newArray;
}

Upvotes: 1

Related Questions