英文:
How to sort an array of objects based on object priority value
问题
我有以下的函数:
export 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 };
} else if (item.priority === targetItemPriority) {
return { ...item, priority: draggedItemPriority };
}
return item;
});
return orderBy(newData, 'priority');
};
我的数据如下:
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[1];
const mockedTargetItem1 = mockedData[3];
但是updatePriorities(mockedData, mockedDraggedItem1, mockedTargetItem1)
给出的结果是:
[
{name: "Item 0", priority: 0}
{name: "Item 2", priority: 1}
{name: "Item 3", priority: 1}
{name: "Item 1", priority: 3}
{name: "Item 4", priority: 4}
{name: "Item 5", priority: 5}
]
而不是预期的:
[
{name: "Item 0", priority: 0}
{name: "Item 2", priority: 1}
{name: "Item 3", priority: 2}
{name: "Item 1", priority: 3}
{name: "Item 4", priority: 4}
{name: "Item 5", priority: 5}
]
mockedTargetItem1
的优先级没有被正确更新。
如果draggedItem
的优先级高于targetItem
的优先级,则工作正常,但如果targetItem
的优先级高于draggedItem
的优先级,则不按预期工作。
有什么建议吗?
英文:
I have function as follows:
export 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 };
} else if (item.priority === targetItemPriority) {
return { ...item, priority: draggedItemPriority };
}
return item;
});
return orderBy(newData, 'priority');
};
My data is 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[1];
const mockedTargetItem1 = mockedData[3];
But updatePriorities(mockedData, mockedDraggedItem1, mockedTargetItem1)
gives me:
[
{name: "Item 0", priority: 0}
{name: "Item 2", priority: 1}
{name: "Item 3", priority: 1}
{name: "Item 1", priority: 3}
{name: "Item 4", priority: 4}
{name: "Item 5", priority: 5}
]
instead of
[
{name: "Item 0", priority: 0}
{name: "Item 2", priority: 1}
{name: "Item 3", priority: 2}
{name: "Item 1", priority: 3}
{name: "Item 4", priority: 4}
{name: "Item 5", priority: 5}
]
The priority of the mockedTargetItem1
is not updated correctly.
If the priority of draggedItem
is higher then priority of targetItem
then it works fine, but if priority of targetItem
is higher than priority of draggedItem
then it does not works as it should.
Any idea?
答案1
得分: 1
使用 (working)
// (item.priority <= maxPriority) 而不是 (item.priority < maxPriority)
if (item.priority >= minPriority && item.priority <= maxPriority) {
const priorityOffset = targetItemPriority < draggedItemPriority ? 1 : -1;
return { ...item, priority: item.priority + priorityOffset };
}
而不是 (bad)
if (item.priority >= minPriority && item.priority < maxPriority) {
const priorityOffset = targetItemPriority < draggedItemPriority ? 1 : -1;
return { ...item, priority: item.priority + priorityOffset };
}
因此,不需要
else if (item.priority === targetItemPriority) {
return { ...item, priority: draggedItemPriority };
}
英文:
Use (working)
// (item.priority <= maxPriority) instead of (item.priority < maxPriority)
if (item.priority >= minPriority && item.priority <= maxPriority) {
const priorityOffset = targetItemPriority < draggedItemPriority ? 1 : -1;
return { ...item, priority: item.priority + priorityOffset };
}
instead of (bad)
if (item.priority >= minPriority && item.priority < maxPriority) {
const priorityOffset = targetItemPriority < draggedItemPriority ? 1 : -1;
return { ...item, priority: item.priority + priorityOffset };
}
therefore, don't need to
else if (item.priority === targetItemPriority) {
return { ...item, priority: draggedItemPriority };
}
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
/**
** For Lodash Compatibility
*/
const { map, orderBy } = _
/**
** Function
*/
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');
};
/**
** Data
*/
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[1];
const mockedTargetItem1 = mockedData[3];
/**
** Test
*/
console.log(updatePriorities(mockedData, mockedDraggedItem1, mockedTargetItem1))
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- end snippet -->
答案2
得分: 0
考虑在这种用例以及所有数组操作中使用lodash的sortBy。
英文:
consider using lodash sortBy for this use case and for all your arrays operations.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论