Если кто-то будет гуглить и не найдет для себя ответа на вопрос, то вот универсальная реализация, перемещение элемента со смещением соседей по индексам whom и where, может быть полезно в ui где с помощью drag&drop перемещаются элементы в списке или карточки, для вывода сортируясь по полю order
interface Todo {
id: number
order: number
title: string
}
interface Test {
whom: number
where: number
expected: number[]
}
const data: Todo[] = [
{ id: 1, order: 1, title: 'delectus aut autem' },
{ id: 2, order: 2, title: 'quis ut nam facilis et officia qui' },
{ id: 3, order: 3, title: 'fugiat veniam minus' },
{ id: 4, order: 4, title: 'et porro tempora' },
{ id: 5, order: 5, title: 'laboriosam mollitia et enim quasi adipisci quia provident illum' },
{ id: 6, order: 6, title: 'qui ullam ratione quibusdam voluptatem quia omnis' },
{ id: 7, order: 7, title: 'illo expedita consequatur quia in' },
{ id: 8, order: 8, title: 'quo adipisci enim quam ut ab' },
{ id: 9, order: 9, title: 'molestiae perspiciatis ipsa' },
{ id: 10, order: 10, title: 'illo est ratione doloremque quia maiores aut' },
]
function swapTodos(todos: Todo[], whom: number, where: number) {
if (whom === where) return todos
const result = (() => {
if (whom < where) {
const start = todos.slice(0, whom)
const neighbors = todos.slice(whom + 1, where + 1)
const tail = todos.slice(where + 1, todos.length)
return [...start, ...neighbors, todos[whom], ...tail]
} else {
const start = todos.slice(0, where)
const neighbors = todos.slice(where, whom)
const tail = todos.slice(whom + 1, todos.length)
return [...start, todos[whom], ...neighbors, ...tail]
}
})()
return result.map((it, i) => ({ ...it, order: i + 1 }))
}
const tests: Test[] = [
{ whom: 1, where: 5, expected: [1, 3, 4, 5, 6, 2, 7, 8, 9, 10] },
{ whom: 0, where: 9, expected: [2, 3, 4, 5, 6, 7, 8, 9, 10, 1] },
{ whom: 4, where: 9, expected: [1, 2, 3, 4, 6, 7, 8, 9, 10, 5] },
{ whom: 8, where: 3, expected: [1, 2, 3, 9, 4, 5, 6, 7, 8, 10] },
{ whom: 9, where: 0, expected: [10, 1, 2, 3, 4, 5, 6, 7, 8, 9] },
{ whom: 9, where: 4, expected: [1, 2, 3, 4, 10, 5, 6, 7, 8, 9] },
]
function runTests() {
console.log('-----------------')
for (const [i, { expected: expect, whom, where }] of tests.entries()) {
console.log(`[Test ${i + 1} start]`)
const result = swapTodos(data, whom, where)
const compare = result.map((it) => it.id)
if (JSON.stringify(compare) !== JSON.stringify(expect)) {
console.warn(`[Test ${i + 1} failed]: Результат не соответствует тому что ожидалось`)
console.log('Result => ', JSON.stringify(compare))
console.log('Expected => ', JSON.stringify(expect))
} else {
console.log(`[Test ${i + 1} passed]: Тест успешно пройден`)
}
console.log('-----------------')
}
}
export default runTests
Ps: Обновление сортировки было моим личным требованием, если нужно можно убрать