I want to change priority
of a draggedItem
with a priority
of a targetItem
.
If they are the same, they should be updated correctly (draggedItem should get priority of targetItem and targetItem priority should be increased by one, because it is the same as priority of draggedItem).
The priority of all other items should also be updated correctly (based on new draggedItem and targetItem priority) and in the end result I should have an array of objects where all objects have different priority.
Thus, I have a function as follows:
const updatePriorities = (data, draggedItem, targetItem) => {
const draggedItemPriority = draggedItem?.priority;
const targetItemPriority = targetItem?.priority;
if (draggedItemPriority === undefined || targetItemPriority === undefined || draggedItemPriority === null || targetItemPriority === null) {
return data;
}
const minPriority = Math.min(draggedItemPriority, targetItemPriority);
const maxPriority = Math.max(draggedItemPriority, targetItemPriority);
const newData = map(data, (item) => {
if (item.priority === draggedItemPriority) {
return { ...item, priority: targetItemPriority };
} else if (item.priority >= minPriority && item.priority <= maxPriority) {
const priorityOffset = targetItemPriority < draggedItemPriority ? 1 : -1;
return { ...item, priority: item.priority + priorityOffset };
}
return item;
});
return orderBy(newData, 'priority');
};
Thus if all objects in the array have different priority, it works fine. Thus with data as follows:
const mockedData = [
{ name: 'Item 0', priority: 0 },
{ name: 'Item 1', priority: 1 },
{ name: 'Item 2', priority: 2 },
{ name: 'Item 3', priority: 3 },
{ name: 'Item 4', priority: 4 },
{ name: 'Item 5', priority: 5 }
];
const mockedDraggedItem1 = mockedData[2];
const mockedTargetItem1 = mockedData[1];
const result = updatePriorities(mockedData, mockedDraggedItem1, mockedTargetItem1)
// The result
[
{ name: 'Item 0', priority: 0 },
{ name: 'Item 2', priority: 1 },
{ name: 'Item 1', priority: 2 },
{ name: 'Item 3', priority: 3 },
{ name: 'Item 4', priority: 4 },
{ name: 'Item 5', priority: 5 }
];
I get correct result, the priority
is updated correctly and Item 2
came to second place (got priority 1) and Item 1
went to third place (got priority 2). That is all fine.
But when I have two objects with the same priority in the array. For example:
const mockedData = [
{ name: 'Item 0', priority: 0 },
{ name: 'Item 1', priority: 1 },
{ name: 'Item 2', priority: 1 },
{ name: 'Item 3', priority: 3 },
{ name: 'Item 4', priority: 4 },
{ name: 'Item 5', priority: 5 }
];
const mockedDraggedItem1 = mockedData[2];
const mockedTargetItem1 = mockedData[1];
Then it does not work as expected, want the priority of draggedItem
and targetItem
is not updated.
I should get next result:
[
{ name: 'Item 0', priority: 0 },
{ name: 'Item 2', priority: 1 },
{ name: 'Item 1', priority: 2 },
{ name: 'Item 3', priority: 3 },
{ name: 'Item 4', priority: 4 },
{ name: 'Item 5', priority: 5 }
];
What should I do to update it correctly?
Thanks in advance.
2
Answers
You can use loadash.sortBy function pass your array of objects to it and you can also pass your options with which you would like to sort it like with which properties you would like to sort an array
Example:
If you want to sort even with equal priorities, then instead of considering priority, you need to examine the entire element. I have modified and commented your function accordingly. It is important to note that in this case, there should not be two completely identical elements in the array, although this could also be handled, but I did not address it now.
Solution # 1
Solution # 2
orderBy()
function, we sort the array and rearrange the priorities based on the indexes in the resulting array.