Wrote a small snippet in ES6. It should be fairly easy to trace through
const getAlternate = (ar) => { const types = []; const objects = {}; const typeCounts = {}; let totalCount = 0; ar.forEach((object) => { if(!types.includes(object.type)) { types.push(object.type); objects[object.type] = object; typeCounts[object.type] = 1; } else { typeCounts[object.type]++; } totalCount++; }); const newAr = []; let typeIndex = 0; while(totalCount > 0) { totalCount--; let type = types[typeIndex]; newAr.push(objects[type]); typeCounts[type]--; if(typeCounts[type] <= 0) { types.splice(typeIndex, 1); typeIndex--; delete objects[type]; delete typeCounts[type]; } typeIndex = (typeIndex + 1) % types.length; } return newAr }
The first thing I do is set some state so that it is easier to iterate over types later, and this includes a list of each type, a copy of an object of each type, and an amount of each type.
From there, I declare a new array and just follow the striping using modulo, deleting everything I no longer need
// here we invoke the function console.log(getAlternate([ { "type":"A", "height":50, "width":80 }, { "type":"A", "height":50, "width":80 }, { "type":"B", "height":20, "width":100 }, { "type":"B", "height":20, "width":100 }, { "type":"C", "height":90, "width":10 } ])); // and, as expected, we get [ {"type":"A","height":50,"width":80}, {"type":"B","height":20,"width":100}, {"type":"C","height":90,"width":10}, {"type":"A","height":50,"width":80}, {"type":"B","height":20,"width":100} ]