I have a scenario where I need to update an array in order to have random objects of the array sorted into other positions but I also need to keep a sequence of all the other elements in the array, I'll give an example of the array and what the output should be like:
let temp1 = [
{id: 1, text: 'info1'},
{id: 2, text: 'info2'},
{id: 3, text: 'info3'},
{id: 4, text: 'info4'},
{id: 5, text: 'info5'}
]
Imagine I need to get the third and fifth elements and move them to the start of the array, I should have an output like this:
let output = [
{id: 3, text: 'info3'},
{id: 5, text: 'info5'}
{id: 1, text: 'info1'},
{id: 2, text: 'info2'},
{id: 4, text: 'info4'}
]
I've tried a few samples I found online but none of them worked as expected since most of them just traded the elements from one place into another.
CodePudding user response:
Hate to loop over arrays several times, but I couldn't do a minimal amount of loops without writing complex code.
Right now, all I do is:
- loop over
valueArr
, - which contains values for a certain property that you want to place first in
temp1
. - I use the values from
valueArr
to find the index throughitemArr.findIndex()
. - That index is then used to splice
temp1
and push the result in a new array. - Finally, I merge the new array and the remaining items in
temp1
, which I return.
I added a parameter to determine which property in your items in temp1
that you want to "sort" by.
let temp1 = [
{id: 1, text: 'info1'},
{id: 2, text: 'info2'},
{id: 3, text: 'info3'},
{id: 4, text: 'info4'},
{id: 5, text: 'info5'}
];
// 'id' [3, 5] temp1
function placeFirstBasedOn(propertyStr, valueArr, itemArr) {
let firstItems = [], index = 0;
for (let value of valueArr) { // 1
index = itemArr.findIndex(item => item[propertyStr] === value); // 3
firstItems.push( itemArr.splice(index, 1)[0] ); // 4
}
return firstItems.concat(itemArr); // 5
}
console.log( placeFirstBasedOn('id', [3, 5], temp1) )
CodePudding user response:
Presented below is one possible way to achieve the desired objective.
Code Snippet
const sortKeepingSeq = (arr, priorityProp, priorityItemsList) => (
structuredClone(arr) // deep-clone to avoid mutating "arr"
.map( // iterate to add priority/sequence-number
(ob, seqNum) => ({ ...ob, seqNum })
).sort( // sort to achieve desired ordering of elements
( // de-structure to directly access desired props
{
[priorityProp] : aval, seqNum : aseq
}, {
[priorityProp] : bval, seqNum : bseq
}
) => {
if (priorityItemsList.includes(aval)) {
if (priorityItemsList.includes(bval)) {
// both a and b are in the "priorityItemsList", so use seqNum to tie-break
return aseq - bseq;
} else {
// b is not in priorityItemsList, so a takes priority
return -1;
}
} else {
if (priorityItemsList.includes(bval)) {
// a is not in priorityItemsList, so b takes priority
return 1;
} else {
// both a and b are NOT in the "priorityItemsList", so use seqNum to tie-break
return aseq - bseq;
}
}
}
).map( // iterate to "remove" the seqNum
({ seqNum, ...rest }) => ({...rest})
)
);
const temp1 = [
{id: 1, text: 'info1'},
{id: 2, text: 'info2'},
{id: 3, text: 'info3'},
{id: 4, text: 'info4'},
{id: 5, text: 'info5'}
];
console.log('sorted keeping sequence