Reputation: 1492
I have the following object inside an array:-
[
{"score": 5, "question": 0, "weight": 2},
{"score": 4, "question": 1, "weight": 2},
{"score": 3, "question": 0, "weight": 4},
{"score": 4, "question": 1, "weight": 4},
{"score": 2, "question": 2, "weight": 4},
{"score": 8, "question": 0, "weight": 2}
]
I am trying to loop through the array so I have the following output, so I am able to run some math against the results:-
[
[
{"score": 5, "question": 0, "weight": 2},
{"score": 4, "question": 1, "weight": 2}
],
[
{"score": 3, "question": 0, "weight": 4},
{"score": 4, "question": 1, "weight": 4},
{"score": 2, "question": 2, "weight": 4}
],
[
{"score": 8, "question": 0, "weight": 2}
]
];
Is there a dynamic way I am able to get array1 to look like array2?
I am using flat JS for this please no jQuery answers.
Thanks in advance.
** Note **
Sometimes each section will have more or less values, this is why I require it to be dynamic.
Upvotes: 1
Views: 56
Reputation: 22866
A bit simplified if splitting by just question: 0
:
data = [ { score: 5, question: 0, weight: 2 }, { score: 4, question: 1, weight: 2 },
{ score: 3, question: 0, weight: 4 }, { score: 4, question: 1, weight: 4 },
{ score: 2, question: 2, weight: 4 }, { score: 8, question: 0, weight: 2 } ]
result = data.reduce((r, v) => (v.question ? r[r.length-1].push(v) : r.push([v]), r), [])
console.log( result )
Upvotes: 0
Reputation: 56744
let scores = [
{"score": 5, "question": 0, "weight": 2},
{"score": 4, "question": 1, "weight": 2},
{"score": 3, "question": 0, "weight": 4},
{"score": 4, "question": 1, "weight": 4},
{"score": 2, "question": 2, "weight": 4},
{"score": 8, "question": 0, "weight": 2}
]
let groupedScores = [], group = [];
scores.forEach((entry) => {
if(entry.question === 0) {
if (group.length) {
groupedScores.push(group);
}
group = [];
}
group.push(entry);
})
groupedScores.push(group)
console.log(groupedScores)
Upvotes: 0
Reputation: 22524
You can use array#reduce
to group your array. Check if the value of question
is 0
then push a new array and add the object to it.
var data = [ {"score": 5, "question": 0, "weight": 2}, {"score": 4, "question": 1, "weight": 2}, {"score": 3, "question": 0, "weight": 4}, {"score": 4, "question": 1, "weight": 4}, {"score": 2, "question": 2, "weight": 4}, {"score": 8, "question": 0, "weight": 2}],
result = data.reduce((r,o) => {
if(o.question == 0)
r.push([]);
r[r.length - 1].push(o);
return r;
},[]);
console.log(result);
Upvotes: 0
Reputation: 15893
var oldA = [
{"score": 5, "question": 0, "weight": 2},
{"score": 4, "question": 1, "weight": 2},
{"score": 3, "question": 0, "weight": 4},
{"score": 4, "question": 1, "weight": 4},
{"score": 2, "question": 2, "weight": 4},
{"score": 8, "question": 0, "weight": 2}
];
var newA = [];
var prevW = 0;
var prevA;
for (var i = 0; i < oldA.length; i++) {
if (oldA[i].weight != prevW) {
prevA = [];
newA.push(prevA);
prevW = oldA[i].weight;
}
prevA.push(oldA[i]);
}
console.log(newA);
Upvotes: 0
Reputation: 191976
You can use Array.reduce()
to convert the 1st to the 2nd array. Whenever the current object weight doesn't match lastWeight
, add another subarray. Always push the current item to the last subarray:
const arr = [
{score: 5, question: 0, weight: 2},
{score: 4, question: 1, weight: 2},
{score: 3, question: 0, weight: 4},
{score: 4, question: 1, weight: 4},
{score: 2, question: 2, weight: 4},
{score: 8, question: 0, weight: 2}
];
let lastWeight = null;
const result = arr.reduce((r, o) => {
if(lastWeight === null || o.weight !== lastWeight) {
lastWeight = o.weight;
r.push([]);
}
r[r.length - 1].push(o);
return r;
}, []);
console.log(result);
Upvotes: 0
Reputation: 386560
You could check weight
and if different, then take a new group.
var data = [{ score: 5, question: 0, weight: 2 }, { score: 4, question: 1, weight: 2 }, { score: 3, question: 0, weight: 4 }, { score: 4, question: 1, weight: 4 }, { score: 2, question: 2, weight: 4 }, { score: 8, question: 0, weight: 2 }],
grouped = data.reduce(function (r, o, i, a) {
if ((a[i - 1] || {}).weight !== o.weight) {
r.push([]);
}
r[r.length - 1].push(o);
return r;
}, []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 122027
You can do this with reduce()
method you just need to keep track of current index for final array.
const data =[
{score: 5, question: 0, weight: 2},
{score: 4, question: 1, weight: 2},
{score: 3, question: 0, weight: 4},
{score: 4, question: 1, weight: 4},
{score: 2, question: 2, weight: 4},
{score: 8, question: 0, weight: 2}
]
const result = data.reduce(function(r, e, i) {
if(i == 0) r = {values: [], counter: 0}
if(e.question == 0 && i != 0) r.counter++
if(!r.values[r.counter]) r.values[r.counter] = [e]
else r.values[r.counter].push(e)
return r;
}, {}).values
console.log(result)
Upvotes: 2