У вас есть два основных варианта:
1) Уведомлять все компоненты, которые получили собственную отсортированную версию списка, когда список изменяется, чтобы они могли скопировать измененный список и отсортировать / отобразить его. Для этого вам нужен способ генерирования событий, например, как класс смешивания:
const EventEmitter = Parent => class EventEmitter extends Parent {
constructor(...args) {
super(...args);
this._emitters = {};
}
trigger(evt, ...args) {
(this._emitters[evt] || []).forEach(emitter => emitter(...args));
}
on(evt, handler) {
(this._emitters[evt] || (this._emitters[evt] = [])).push(handler);
}
};
Затем вы можете проксировать массив, чтобы при каждом изменении вызывалось событие обновления:
const ChangeEmitter = Parent => {
const Mixin = EventEmitter(Parent);
return (...args) => new Proxy(
new Mixin(...args),
{
set(obj, prop, value) {
const result = Reflect.set(...arguments);
obj.trigger("update", obj);
return result;
}
}
);
};
Это выглядит очень сложно, но теперь мы можем сделать это:
// Our source of truth:
const base = new ChangeEmitter(Array);
// One of the functions that renders the data:
function renderSorted(array) {
const sorted = array.sort();
document.body.innerHTML = sorted;
}
renderSorted(base); // Initial render
base.on("update", renderSorted);
base[0] = 1;
Поэтому, когда мы обновляем базовый массив, все средства визуализации будут вызываться снова, и все может обновляться.
2) Создайте несколько отсортированных массивов и примените каждую мутацию ко всем из них. Для этого нам понадобится отсортированный массив:
class SortedArray extends Array {
constructor(sorter, ...args) {
super(...args);
this.sorter = sorter;
this.sort(sorter);
}
// Do insertion sort
add(el) {
let index = 0;
while(index <= this.length && this.sorter(el, this[index]) > 0) index++;
this splice(index, 0, el);
}
remove(el) {
this.splice(this.indexOf(el), 1);
}
}
И способ параллельного изменения нескольких массивов:
const unifyArrays = (...arrays) => ({
add(el) { arrays.forEach(arr => arr.add(el)); },
remove(el) { arrays.forEach(arr => arr.remove(el)); }
});
Итак, теперь вы можете сделать:
const sorted = new SortedArray((a, b) => a - b);
const reversed = new SortedArray((a, b) => b - a);
const base = unifyArrays(sorted, reversed);
base.add(1);
Конечно, вы можете комбинировать оба подхода, так что четные числа будут генерироваться при замене массивов.