在保持元素一致性的同时旋转数组元素的最佳方式'id

Best way to rotate elements of an array while preserving the consistency of the elements' id

本文关键字:方式 最佳 id 数组元素 元素 一致性 旋转      更新时间:2023-09-26

给定一个对象数组:

var array = [
    { some_id: 0, name:'a' },
    { some_id: 1, name:'b' },
    { some_id: 2, name:'c' },
    { some_id: 3, name:'d' },
    { some_id: 4, name:'e' },
    { some_id: 5, name:'f' }
];

some_id = 4的对象移动到位置some_id = 1,同时更新移动的元素的some_id值,以使变换后数组中some_id值的顺序保持不变的最佳方法是什么?

例如,将some_id = 4移动到some_id = 1之后,您将得到:

array = [
    { some_id: 0, name:'a' },
    { some_id: 1, name:'e' },
    { some_id: 2, name:'b' },
    { some_id: 3, name:'c' },
    { some_id: 4, name:'d' },
    { some_id: 5, name:'f' }
];

本质上应该发生的是:

  1. 我们将{ some_id: 4, name:'e' }移动到{ some_id: 1, name:'e' }
  2. 我们将{ some_id: 1, name:'b' }移动到{ some_id: 2, name:'b' }
  3. 我们将{ some_id: 2, name:'c' }移动到{ some_id: 3, name:'c' }
  4. 我们将{ some_id: 3, name:'d' }移动到{ some_id: 4, name:'d' }

因此,我们只是旋转元素并更改some_id值。请注意,我们不接触对象的任何其他属性。

“最佳";我认为;在更新元素标识符的同时拖放元素";如下所示:

function move(key, src, to, array)                                              {
    var length   = array.length
    if (length === 0) return array
    var srcIndex = -1
    var toIndex  = -1
    var index    = 0
    loop: do switch (array[index][key])                                         {
        case src: srcIndex = index++; break loop
        case to:  toIndex  = index++; break loop                                }
    while (++index < length)
    if (index === length) return array
    if (srcIndex < 0) do if (array[index][key] === src)                         {
            srcIndex = index; break                                             }
        while (++index < length)
    else do if (array[index][key] === to)                                       {
            toIndex  = index; break                                             }
        while (++index < length)
    if (index === length) return array
    var step = toIndex < srcIndex ? 1 : -1
        src  = array[srcIndex]
    do                                                                          {
        to   = array[toIndex]
        array[toIndex] = src
        src[key] = toIndex
        toIndex += step
        src = to                                                                }
    while (toIndex !== srcIndex)
    array[toIndex] = src
    src[key] = toIndex
    return array                                                                }
<script>
setTimeout(function () {
    var array = [
        { some_id: 0, name: 'a' },
        { some_id: 1, name: 'b' },
        { some_id: 2, name: 'c' },
        { some_id: 3, name: 'd' },
        { some_id: 4, name: 'e' },
        { some_id: 5, name: 'f' }
    ];
    print(move("some_id", 4, 1, array));
    print(move("some_id", 1, 4, array));
    function print(array) {
        alert("['n" + array.map(function (obj) {
            return "    { some_id: " + obj.some_id +
                ", name: '" + obj.name + "' }";
        }).join(",'n") + "'n]");
    }
}, 0);
</script>

这就是我正在做的:

  1. 第一个loop找到srcIndextoIndex,以先到者为准
  2. 如果我们找到srcIndextoIndex,并且它不是array的最后一个索引(这意味着我们也可以找到另一个索引),那么我们继续。否则,我们返回array
  3. 我们检查哪个索引仍然没有找到,然后循环遍历其余元素来找到它
  4. 如果找不到第二个索引,则返回array。否则我们继续
  5. 现在我们有了这两个索引,我们可以简单地重新排列最后一个循环中的元素

希望能有所帮助。

您可以使用splice方法,该方法允许您将元素从元素添加/删除到数组中。将索引1的元素移动到索引4:

element = arr.splice(1, 1);
arr.splice(4, 0, element);

你可以交替地将这两个组合成一行:

arr.splice(4, 0, arr.splice(1,1));

以下是W3Schools关于拼接方法的页面:http://www.w3schools.com/jsref/jsref_splice.asp

就更新id而言,我会循环遍历数组,使id与当前索引匹配(因为在您的示例中,您只是移动元素e,而不是用元素b替换它):

arr.forEach( function(element, index) {
    element.some_id = index;
});

这是AaditMShah答案的一个稍微修改、重新格式化的版本

function move(key, src, to, array) {
    var srcIndex = -1, toIndex  = -1;
    for( var i = 0, l = array.length; i < l; i++ ) {
       switch(array[i][key]) {
           case src: 
              srcIndex = i; 
              break;
           case to: 
              toIndex  = i; 
              break;
       }
       if ( srcIndex > -1 && toIndex > -1 ) {
          break;
       }
    }
    if ( (srcIndex == -1 || toIndex == -1) || (srcIndex == toIndex )
      return array
    var step = toIndex < srcIndex ? 1 : -1
        src  = array[srcIndex]
    do {
        to   = array[toIndex]
        array[toIndex] = src
        src[key] = toIndex
        toIndex += step
        src = to
    } while (toIndex !== srcIndex);
    array[toIndex] = src
    src[key] = toIndex
    return array                                                                
}