set-array
Version:
Set array items declaratively
73 lines (50 loc) • 1.23 kB
JavaScript
export const applyUpdates=(array,updates,{merge})=>{
const{array:arrayA,updates:updatesA}=applyAny(array,updates,merge);
const newArray=[];
let previousIndex=-1;
for(const update of updatesA){
previousIndex=applyUpdate({
update,
array:arrayA,
newArray,
previousIndex,
merge
})
}
pushValues(arrayA,newArray,previousIndex+1,arrayA.length);
return newArray
};
const applyAny=(array,updates,merge)=>{
if(updates.length===0||!updates[0].any){
return{array,updates}
}
const[{items},...updatesA]=updates;
const arrayA=array.flatMap((_,index)=>
applyMerge({items,array,index,merge})
);
return{array:arrayA,updates:updatesA}
};
const applyUpdate=({
update:{index,items},
array,
newArray,
previousIndex,
merge
})=>{
pushValues(array,newArray,previousIndex+1,Math.ceil(index));
const itemsA=applyMerge({items,array,index,merge});
pushValues(itemsA,newArray,0,itemsA.length);
return Math.floor(index)
};
const applyMerge=({items,array,index,merge})=>{
if(merge===undefined||!Number.isInteger(index)){
return items
}
const oldValue=array[index];
return items.map((newValue)=>merge(oldValue,newValue))
};
const pushValues=(array,newArray,from,to)=>{
for(let index=from;index<to;index+=1){
newArray.push(array[index])
}
};