如何根据对象的优先级值对数组进行排序

huangapple go评论56阅读模式
英文:

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 &lt;= maxPriority) instead of (item.priority &lt; maxPriority)
if (item.priority &gt;= minPriority &amp;&amp; item.priority &lt;= maxPriority) {
  const priorityOffset = targetItemPriority &lt; draggedItemPriority ? 1 : -1;
  return { ...item, priority: item.priority + priorityOffset };
}

instead of (bad)

if (item.priority &gt;= minPriority &amp;&amp; item.priority &lt; maxPriority) {
  const priorityOffset = targetItemPriority &lt; 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) =&gt; {
  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) =&gt; {
    if (item.priority === draggedItemPriority) {
      return { ...item, priority: targetItemPriority };
    } else if (item.priority &gt;= minPriority &amp;&amp; item.priority &lt;= maxPriority) {
      const priorityOffset = targetItemPriority &lt; draggedItemPriority ? 1 : -1;
      return { ...item, priority: item.priority + priorityOffset };
    } 
    return item;
  });

  return orderBy(newData, &#39;priority&#39;);
};

/**
 ** Data
 */
const mockedData = [
  { name: &#39;Item 0&#39;, priority: 0 },
  { name: &#39;Item 1&#39;, priority: 1 },
  { name: &#39;Item 2&#39;, priority: 2 },
  { name: &#39;Item 3&#39;, priority: 3 },
  { name: &#39;Item 4&#39;, priority: 4 },
  { name: &#39;Item 5&#39;, priority: 5 }
];
const mockedDraggedItem1 = mockedData[1];
const mockedTargetItem1 = mockedData[3];

/**
 ** Test
 */
console.log(updatePriorities(mockedData, mockedDraggedItem1, mockedTargetItem1))

<!-- language: lang-html -->

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js&quot; integrity=&quot;sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

答案2

得分: 0

考虑在这种用例以及所有数组操作中使用lodash的sortBy。

英文:

consider using lodash sortBy for this use case and for all your arrays operations.

huangapple
  • 本文由 发表于 2023年6月19日 19:58:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76506400.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定