При удалении элемента из массива вам никогда не придется выполнять повторную сортировку.
Вместо нажатия и повторной сортировки, вы можете вставить элемент, используя вашу сортировкуопределение.
Вам нужно будет только определить отсортированную функцию инъекции, поскольку у наблюдаемых массивов уже есть метод remove
:
const sorter = (a, b) => a > b ? 1 : a < b ? -1 : 0;
const leftNumbers = ko.observableArray(
[3,5,1,2].sort(sorter)
);
const rightNumbers = ko.observableArray(
[4,1,3,5].sort(sorter)
);
// There are many ways to write this function, which you can probable
// find on stack overflow. The destructuring probably makes this slower
// than just re-sorting. I'll leave it up to you to optimize for performance.
const injectSorted = (sorter, arr, nr) => {
const pos = arr.findIndex(x => sorter(x, nr) > -1);
if (pos === -1) return arr.concat(nr);
return [
...arr.slice(0, pos),
nr,
...arr.slice(pos)
];
};
// Notice how we don't need to re-sort
const moveFromTo = (arr1, arr2) => x => {
arr2(injectSorted(sorter, arr2(), arr1.remove(x)));
};
ko.applyBindings({ leftNumbers, rightNumbers, moveFromTo });
div { display: flex; justify-content: space-around; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<p>Click numbers to move between lists</p>
<div>
<ul data-bind="foreach: leftNumbers">
<li data-bind="click: moveFromTo(leftNumbers, rightNumbers), text: $data"></li>
</ul>
<ul data-bind="foreach: rightNumbers">
<li data-bind="click: moveFromTo(rightNumbers, leftNumbers), text: $data"></li>
</ul>
</div>