'Delete an element from the array and update order
I have an array of objects in the state. The object has the order property. I need order prop for drag and drop. The list is sorted by order. Also, there is a function to remove an item from the list. How to correctly remove an element from an array with updating the order property?
const deleteTodo = (id) => {
//I tried using map but it doesn't work
setTodos(todos.map((todo, index) => {
if (todo.id !== id) {
return { ...todo, order: index + 1 }
}
return todo
}))
}
/* for example:
[{title: 'apple', order: 1}, {title: 'banana', order: 2}, {title: 'pear', order: 3}] => delete banana => [{title: 'apple', order: 1}, {title: 'pear', order: 2}] */
I wrote this solution based on the suggested options:
const deleteTodo = (id) => {
const newTodos = todos
.filter(todo => todo.id !== id)
.map((todo, index) => ({ ...todo, order: index + 1 }))
setTodos(newTodos)
}
Solution 1:[1]
- Filter to delete
- map to change the order value
const items = [{
title: 'apple',
order: 1
}, {
title: 'banana',
order: 2
}, {
title: 'pear',
order: 3
}]
//Delete {title: 'banana', order: 2}
const newItems = items.filter(el => el.title !== "banana").map(el => el.order > 2 ? ({ ...el,
order: el.order - 1
}) : el)
console.log(newItems)
Solution 2:[2]
You have to filter the array that doesn't have the specific id and assign its order later
const deleteTodo = (id) => {
const newTodos = todos.filter(todo => todo.id !== id)
newTodos.map((todo, index) => {
return {
...todo,
order: index
}
})
setTodos(newTodos)
}
Solution 3:[3]
This function will get the result you are looking for but not with removing. I recreate the array with the objects excluding the one you want to remove and give them the new ordering.
const data = [{title: 'apple', order: 1}, {title: 'banana', order: 2}, {title: 'pear', order: 3}];
function removeObjectAndReorder(data, orderToRemove){
let result = [];
let counter = 0;
for (let i = 0; i < data.length; i++){
if (i+1 !== orderToRemove){
result.push({
'title': data[i].title,
'order': ++counter,
})
}
}
return result;
}
console.log(removeObjectAndReorder(data,2)); // Remove banana (order = 2)
Solution 4:[4]
const list = [
{id: 1, title: 'apple', order: 1},
{id: 2, title: 'banana', order: 2},
{id: 3, title: 'pear', order: 3},
];
const deleteItem = (id) => {
const newList = [...list]
.sort((a,b) => a.order - b.order) // make sure list is in order
.filter(el => el.id !== id) // filter out the selected item
.map((el, i) => ({...el, order: i+1})); // Change the order values
return newList;
}
console.log(deleteItem(2));
Solution 5:[5]
You can try this one
const deleteTodo = (id) => {
const targetIndex = todos.findIndex((todo) => todo.id === id);
if (targetIndex < 0) {
// target element was not found. you need to handle this case
return;
}
const updatedTodos = todos.reduce((accumulated, todo, index) => {
if (index < targetIndex) {
accumulated.push(todo);
} else if (index > targetIndex) {
accumulated.push({ ...todo, order: todo.order - 1 });
}
return accumulated;
}, []);
setTodos(updatedTodos);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Cesare Polonara |
| Solution 2 | Geeky Quentin |
| Solution 3 | holydragon |
| Solution 4 | bgcodes |
| Solution 5 |
