2

我一直在努力解决这个问题,但它不起作用。

我正在使用一些专有技术,一次只允许移动一个元素。超级烦。将其视为 list.moveRow(之前,之后)。

所以想象一个包含 10 个项目的待办事项列表:1, 2, 3, 4, 5, 6, 7, 8, 9, 10

我想要做的是在那里重新排序多个项目,所以说我选择 items 2, 6, 7, and 8

然后我拖放到位置4

这个想法是元素现在应该是有序的:1, 3, 2, 6, 7, 8, 4, 5, 9, 10.

有没有一种简单的方法可以做到这一点?我尝试使用额外的变量来跟踪由于移动的元素会抛出索引而导致的偏移量,但它非常混乱。:(

4

3 回答 3

0

这真的取决于语言。

假设您有一种简单的方法来获取每个项目的 isSelected() ,最简单和最通用的似乎是将一个新数组构建为列表(即从第一个索引添加到最后一个索引):

  • 按顺序添加未选中的项目,直到插入位置
  • 添加所选项目
  • 添加剩余的未选择项目

然后替换旧数组。

在伪代码中:

func(int[] items, bool[] isselected, int insertpos) {
   newitems = new int[items.length]
   i=0
   for (j=0; j<items.length; j++) {
      if j==insertpos {
          for (k=0; k<items.length; k++) {
              if isselected[k] {
                  newitems[i++] = items[k]
              }
          }
      } else if !isselected[j] {
          newitems[i++] = items[j]
      }
   }
   return newitems
}

如果你想要高性能和就地修改......那是另一回事......

于 2012-06-28T19:43:39.270 回答
0

坐下来把它写出来,想出了一个合理的解决方案。这似乎工作正常:

// Reorder list
function reorder(items, index)
{        
    // When we move, we have to account for previously moved rows too
    //  Go from bottom-most selected row first to preserve order
    for (var i = items.length - 1, itemOffset = 0, indexOffset = 0; i >= 0; --i) 
    {
        // Move
        list.moveRow(items[i] + itemOffset, index + indexOffset);

        // Change offsets based on location
        //  If next row index is after target index, add to row offset
        if (i-1 >= 0 && items[i-1] >= index) {
            itemOffset++;
        } else {    // If next index is before target, subtract from target
            itemOffset= 0;
            indexOffset--;
        }
    }
}
于 2012-06-28T21:22:34.523 回答
0

我希望我能早点找到这个。无论如何,在现代 JS 中,可以(并且希望!)在没有条件的情况下做到这一点,并且有一个优雅的算法可以通过使用占位符来实现这一点。

具体来说,我们可以使用 aSymbol作为在有序集中移动的元素的替代。这样,索引算术就被消除了(并且随之而来的是大量的条件和地方错误恶化的地方)。

工作原理基本上是这样的:

withGroupRepositioned(["a", "b", "c", "d"], ["a", "b"], 0) // [ 'a', 'b', 'c', 'd' ]
withGroupRepositioned(["a", "b", "c", "d"], ["a", "b"], 1) // [ 'a', 'b', 'c', 'd' ]
withGroupRepositioned(["a", "b", "c", "d"], ["a", "b"], 2) // [ 'a', 'b', 'c', 'd' ]
withGroupRepositioned(["a", "b", "c", "d"], ["a", "b"], 3) // [ 'c', 'a', 'b', 'd' ]
withGroupRepositioned(["a", "b", "c", "d"], ["b", "a"], 2) // [ 'b', 'a', 'c', 'd' ]
withGroupRepositioned(["a", "b", "c", "d"], ["b", "a"], 3) // [ 'c', 'b', 'a', 'd' ]
withGroupRepositioned(["a", "b", "c", "d"], ["a", "c"], 4) // [ 'b', 'd', 'a', 'c' ]

整个功能是:

const PLACEHOLDER = Symbol();
function withGroupRepositioned(inOrderedSet, valuesToReposition, toIndex) {
  // Do not damage the given set
  const cpy = [].concat(inOrderedSet);

  // Step 1. Replace all traveling elements with placeholders, in place.
  valuesToReposition.forEach((v) => cpy[cpy.indexOf(v)] = PLACEHOLDER);

  // Step 2. Reinsert values as a group, where we want them.
  cpy.splice(toIndex, 0, ...valuesToReposition);

  // Step 3. Remove placeholders.
  return cpy.filter((v) => v !== PLACEHOLDER);
}

如果要就地执行重新排列,可以删除第一个数组复制操作。

于 2019-01-20T20:01:11.110 回答