user2062455
user2062455

Reputation: 421

How to group an array into sub arrays in sequence

I have the following json

[ 
 { check:false, value:"some value" },
 { check:true,  value:"some value" },
 { check:false, value:"some value" },
 { check:false, value:"some value" },
 { check:false, value:"some value" },
 { check:true,  value:"some value" },
 { check:true,  value:"some value" },
]

and i want to group like this

[ 
 { stack: [
           { check:false, value:"some value" }
          ]
 },
 { check:true,  value:"some value" },
 { stack: [
           { check:false, value:"some value" },
           { check:false, value:"some value" },
           { check:false, value:"some value" },
          ]
 },
 { check:true,  value:"some value" },
 { check:true,  value:"some value" },
]

which means, i would like to go through the array and IF "check" is true leave it as it, IF "check" is false group and create a sub.

i've tried map the original array according to the check, but this just groups in to 2 subarrays.

any idea how can that be done?

thank you

Upvotes: 1

Views: 1205

Answers (3)

Islam Sayed
Islam Sayed

Reputation: 56

You have to loop over the array (arr) and check if the check value is false. If so then put it inside an empty array (chunckArr) and push it into the new array (newArr), and if value of check is true just push the object into newArr.

const arr = [
  { check:false, value:"some value" },
  { check:true,  value:"some value" },
  { check:false, value:"some value" },
  { check:false, value:"some value" },
  { check:false, value:"some value" },
  { check:true,  value:"some value" },
  { check:true,  value:"some value" },
];
let newArr = [];
for(const elem of arr) {
  let chunckArr = [];
  
  if (!elem.check) {
	chunckArr[0] = elem;
	newArr.push(chunckArr);
  } else {
    newArr.push(elem);
  }
};

console.log(newArr);

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386610

A slightly different approach by using the previous element from the array for checking.

var data = [{ check: false, value: "some value" }, { check: true, value: "some value" }, { check: false, value: "some value" }, { check: false, value: "some value" }, { check: false, value: "some value" }, { check: true, value: "some value" }, { check: true, value: "some value" }],
    grouped = data.reduce((r, o, i, { [i - 1]: p }) => {
        if (o.check) {
            r.push(o);
            return r;
        }
        if (!p || p.check) r.push({ stack: [o] });
        else r[r.length - 1].stack.push(o);
        return r;
    }, []);

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

Upvotes: 1

Nenad Vracar
Nenad Vracar

Reputation: 122047

You could do this using reduce method and if the check is false you can also check if the last inserted element is object with stack property or not.

const data = [  { check:false, value:"some value" }, { check:true,  value:"some value" }, { check:false, value:"some value" }, { check:false, value:"some value" }, { check:false, value:"some value" }, { check:true,  value:"some value" }, { check:true,  value:"some value" },]

const result = data.reduce((r, e) => {
  const last = r[r.length - 1];
  if (e.check) r.push(e);
  else {
    if (!last || !('stack' in last)) r.push({ stack: [e]})
    else last.stack.push(e); 
  }
  return r;
}, []);

console.log(result)

Upvotes: 4

Related Questions