简体   繁体   中英

JS Loop through array based on key values and add values

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.

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) 

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; } 

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); 

 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); 

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); 

 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) 

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 ) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM