Here is a solution based on our conversation.
There are many similar ways to do this, but the key is to store the reverse index for the lookup in the model itself, so each model "knows" where it is in the model index.
Edit:
There was a bug in my first example that would have showed up when the array became sparse due to array.length shrinking.
This is a more advanced example that gets rid of the bug and has a dataIndex class that is responsible for indexing, and where models can have reverse lookups for multiple indexes.
class dataIndex {
constructor(indexId) {
this.vec = [];
this.indexId = indexId;
this.indexNext = 0;
}
indexModel(model) {
this.vec[model.lookup[this.indexId] = this.indexNext++] = model;
return this;
}
}
class dataModel {
constructor(data) {
this.data = data;
this.lookup = new Map();
}
static compareData(a, b) {
return (a.data === b.data) ? 0:
(a.data > b.data) ? 1 : -1;
}
}
const modelIndex = new dataIndex('primary');
const sortedIndex = new dataIndex('sorted');
for (let i = 0; i < 10; i++) {
let newModel = new dataModel(Math.random());
modelIndex.indexModel(newModel);
}
const ordered = modelIndex.vec.sort((a, b) => dataModel.compareData(a, b))
ordered.forEach(model => sortedIndex.indexModel(model));
console.log(ordered);
Output:
[
dataModel {
data: 0.08420389624353097,
lookup: Map(0) { primary: 9, sorted: 0 }
},
dataModel {
data: 0.1528733550120258,
lookup: Map(0) { primary: 7, sorted: 1 }
},
dataModel {
data: 0.28483626134194595,
lookup: Map(0) { primary: 8, sorted: 2 }
},
dataModel {
data: 0.3257986769682104,
lookup: Map(0) { primary: 5, sorted: 3 }
},
dataModel {
data: 0.3409113857134396,
lookup: Map(0) { primary: 3, sorted: 4 }
},
dataModel {
data: 0.3841968173496322,
lookup: Map(0) { primary: 1, sorted: 5 }
},
dataModel {
data: 0.40414714769598237,
lookup: Map(0) { primary: 4, sorted: 6 }
},
dataModel {
data: 0.5817767975980099,
lookup: Map(0) { primary: 0, sorted: 7 }
},
dataModel {
data: 0.8091360598739015,
lookup: Map(0) { primary: 2, sorted: 8 }
},
dataModel {
data: 0.8217632650897493,
lookup: Map(0) { primary: 6, sorted: 9 }
}
]