please is there a way to turn subject1 to subject2. if you notice, the chemistry in the subject2 occurs at interval of 3.
const subjects = [
{ "name": "Math", "score": 32 },
{ "name": "Chemistry", "score": 17 },
{ "name": "English", "score": 17 },
{ "name": "Math", "score": 55 },
{ "name": "Chemistry", "score": 21 },
{ "name": "Chemistry", "score": 75 },
{ "name": "Chemistry", "score": 45 },
{ "name": "Physics", "score": 9 },
{ "name": "Physics", "score": 4 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 11 },
];
const Newsubjects = [
{ "name": "Math", "score": 32 },
{ "name": "English", "score": 17 },
{ "name": "Chemistry", "score": 17 }, *********
{ "name": "Math", "score": 55 },
{ "name": "Physics", "score": 9 },
{ "name": "Chemistry", "score": 21 }, *********
{ "name": "Physics", "score": 4 },
{ "name": "Physics", "score": 21 },
{ "name": "Chemistry", "score": 75 }, *********
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Chemistry", "score": 45 }, *********
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
];
SO i created this simple for loop, It works well
const subjects = [
{ "name": "Math", "score": 32 },
{ "name": "Chemistry", "score": 17 },
{ "name": "English", "score": 17 },
{ "name": "Math", "score": 55 },
{ "name": "Chemistry", "score": 21 },
{ "name": "Chemistry", "score": 75 },
{ "name": "Chemistry", "score": 45 },
{ "name": "Geo", "score": 9 },
{ "name": "Physics", "score": 4 },
{ "name": "Arab", "score": 21 },
{ "name": "Hausa", "score": 11 },
{ "name": "Yoruba", "score": 21 },
{ "name": "Commerce", "score": 11 },
{ "name": "Spanish", "score": 21 },
{ "name": "German", "score": 11 },
{ "name": "Gov", "score": 11 },
];
let filteredArray = subjects.filter(value => value.name == "Chemistry");
let filteredArray2 = subjects.filter(value => value.name != "Chemistry");
//console.log(filteredArray)
for (let i = 0; i <= filteredArray2.length; i++)
{
if (i % 3 == 0 ) {
filteredArray2.splice( i, 0, { "name": "Agric", "score": 11 } )
}
}
console.log(filteredArray2)
Then whenever I try to change the value of the splice to the filteredArray, so that it won't be hardcoded { "name": "Agric", "score": 11 }
I added another for loop because I wanted to add the value from the filtered array
for (let i = 0; i <= filteredArray2.length; i++)
{
for (let j = 0; j <= filteredArray.length; j++)
{
if (i % 3 == 0) {
filteredArray2.splice(i,0, filteredArray[j],)
}
}
}
Please am open to suggestions or any idea As the goal is to just rearrange the array based on the chemistry object and make it occur with the interval of 3
Thank you for your time
You could add some fixes to your code.
since you insert an element to an array you should increment the loop index (i++
) so the loop would accommodate the new array length.
based on your desired output you should insert at the loop index minus 1 and skip the zero index from moonwave99's answer - use i % 3 === 2
.
to get an element from the chemistry array use Array::shift()
to get elements
break the loop if there's no more chemistry elements to insert.
let filteredArray = subjects.filter(value => value.name == "Chemistry");
let filteredArray2 = subjects.filter(value => value.name != "Chemistry");
for (let i = 0; i <= filteredArray2.length && filteredArray.length; i++){
i % 3 === 2 && filteredArray2.splice( i++ , 0, filteredArray.shift());
}
filteredArray2.forEach(item => console.log(JSON.stringify(item)));
<script>
const subjects = [
{ "name": "Math", "score": 32 },
{ "name": "Chemistry", "score": 17 },
{ "name": "English", "score": 17 },
{ "name": "Math", "score": 55 },
{ "name": "Chemistry", "score": 21 },
{ "name": "Chemistry", "score": 75 },
{ "name": "Chemistry", "score": 45 },
{ "name": "Physics", "score": 9 },
{ "name": "Physics", "score": 4 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 11 },
];
</script>
It's possible to make the code at least twice faster with building the result array manually. Also avoid Array::shift()
to mutate an array since write operations are slow.
let filteredArray = subjects.filter(value => value.name == "Chemistry");
let filteredArray2 = new Array(subjects.length);
let j = 0;
for(let i = 0, n = 0; i < subjects.length; i++){
if(subjects[i].name === 'Chemistry'){
continue;
}
if(j % 3 === 2 && n < filteredArray.length){
filteredArray2[j++] = filteredArray[n++];
}
filteredArray2[j++] = subjects[i];
}
filteredArray2.forEach(item => console.log(JSON.stringify(item)));
<script>
const subjects = [
{ "name": "Math", "score": 32 },
{ "name": "Chemistry", "score": 17 },
{ "name": "English", "score": 17 },
{ "name": "Math", "score": 55 },
{ "name": "Chemistry", "score": 21 },
{ "name": "Chemistry", "score": 75 },
{ "name": "Chemistry", "score": 45 },
{ "name": "Physics", "score": 9 },
{ "name": "Physics", "score": 4 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 11 },
];
</script>
And a benchmark:
<script benchmark data-count="3000000">
const subjects = [
{ "name": "Math", "score": 32 },
{ "name": "Chemistry", "score": 17 },
{ "name": "English", "score": 17 },
{ "name": "Math", "score": 55 },
{ "name": "Chemistry", "score": 21 },
{ "name": "Chemistry", "score": 75 },
{ "name": "Chemistry", "score": 45 },
{ "name": "Physics", "score": 9 },
{ "name": "Physics", "score": 4 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 21 },
{ "name": "Physics", "score": 11 },
{ "name": "Physics", "score": 11 },
];
// @benchmark original
{
let filteredArray = subjects.filter(value => value.name == "Chemistry");
let filteredArray2 = subjects.filter(value => value.name != "Chemistry");
for (let i = 0; i <= filteredArray2.length && filteredArray.length; i++){
i % 3 === 2 && filteredArray2.splice( i++ , 0, filteredArray.shift());
}
filteredArray2;
}
// @benchmark optimized
{
let filteredArray = subjects.filter(value => value.name == "Chemistry");
let filteredArray2 = new Array(subjects.length);
let j = 0;
for(let i = 0, n = 0; i < subjects.length && n < filteredArray.length; i++){
if(subjects[i].name === 'Chemistry'){
continue;
}
if(j % 3 === 2 && n < filteredArray.length){
filteredArray2[j++] = filteredArray[n++];
}
filteredArray2[j++] = subjects[i];
}
filteredArray2;
}
// @benchmark moonwave99
function arrangeBySubject(subjects, subject) {
const subjectEntries = subjects.filter((x) => x.name === subject);
const nonSubjectEntries = subjects.filter((x) => x.name !== subject);
return Array.from({ length: subjects.length }, (_, index) => {
if (index % 3 === 2 && subjectEntries.length) {
return subjectEntries.shift();
}
return nonSubjectEntries.shift();
});
}
// @run
arrangeBySubject(subjects, 'Chemistry');
</script>
<script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>