I have an array of any values, as well as data associated with each value.
This data is stored as Record<string,FooData>
where the key is generated using the index within the array.
However, I am struggling to implement a correct solution for shifting the meta back to their correct place after the array has been filtered.
An example scenario:
[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' ]
The array is then filtered outside of my function. The old array is unknown, all that remains is the following data:
[ 'a', 'b', 'd', 'e', 'h', 'i', 'j' ]
. Remember that it's unknown[]
and not sorted.[ 2, 5, 6 ]
(corresponding to [ 'c', 'f', 'g' ]
)10
Knowing this information, how can I shift all records to their new location? ('h'
moved from index 7
to 4
)
I do not need to remove dangling data from the end of the array. All data in the record is from before the filter.
Reproducible Example
function getKey(i: number) {
return `unknownProcess[${i}]`;
}
// Array before the filter
const originalArray = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' ]
// Associated data is the upper case variant of the letter
const associatedData: Record<string, string> = {}
originalArray.forEach((letter, i) => {
associatedData[getKey(i)] = letter.toUpperCase();
});
// data[getKey(0)] === 'A'
// data[getKey(2)] === 'C'
// Array after filter
// [ 'a', 'b', 'd', 'e', 'h', 'i', 'j' ]
// data[getKey(0)] === 'A'
// data[getKey(2)] === 'C' // should be 'D' now
// data[getKey(4)] === 'E' // should be 'H' now
type FooData = any
// separate file, cannot access data above
function shiftDataFromFilter(filteredArray: unknown[], data: Record<string, FooData>, removedIndeces: number[], lengthBeforeFilter: number) {
// to get data of index 0
const fooData = data[getKey(0)];
}
You can create a filtered indices array and then create a map object of filtered:original index:
// const originalArray = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' ]
// const filteredArray = [ 'a', 'b', 'd', 'e', 'h', 'i', 'j' ];
const lengthBeforeFilter = 10
const removedIndices = [2,5,6];
const removedIndicesSet = new Set(removedIndices);
const filteredIndices = new Array(lengthBeforeFilter).fill(null).map((e,i)=>i).filter(e => !(removedIndicesSet.has(e)))
const keyMap = filteredIndices.reduce((a,c,i)=>(a[i]=c,a),{});
console.log(keyMap);
With the keyMap
, you can use
data[getKey(keyMap[2])]
to get the correct result or shift data
accordingly.