【问题标题】:Move an array element from one array position to another将数组元素从一个数组位置移动到另一个位置
【发布时间】:2011-07-15 11:14:36
【问题描述】:

我很难弄清楚如何移动数组元素。例如,给定以下内容:

var arr = [ 'a', 'b', 'c', 'd', 'e'];

如何编写函数将'd' 移动到'b' 之前?

还是在'c' 之后'a'

移动后,其余元素的索引应更新。这意味着在移动后的第一个示例中,

arr = ['a', 'd', 'b', 'c', 'e']

这看起来应该很简单,但我无法理解它。

【问题讨论】:

  • 使用 ES6 const changeValuePosition = (arr, init, target) => {[arr[init],arr[target]] = [arr[target],arr[init]]; return arr}
  • 这只是交换inittarget 的元素。

标签: javascript arrays


【解决方案1】:

我认为最好的方法是为数组定义一个新属性

Object.defineProperty(Array.prototype, 'move', {
    value: function (old_index, new_index) {
        while (old_index < 0) {
            old_index += this.length;
        }
        while (new_index < 0) {
            new_index += this.length;
        }
        if (new_index >= this.length) {
            let k = new_index - this.length;
            while ((k--) + 1) {
                this.push(undefined);
            }
        }
        this.splice(new_index, 0, this.splice(old_index, 1)[0]);
        return this;
    }
});

console.log([10, 20, 30, 40, 50].move(0, 1));  // [20, 10, 30, 40, 50]
console.log([10, 20, 30, 40, 50].move(0, 2));  // [20, 30, 10, 40, 50]

【讨论】:

    【解决方案2】:

    此方法将保留原始数组,并检查边界错误。

    const move = (from, to, arr) => {
        to = Math.max(to,0)
        from > to 
            ? [].concat(
                arr.slice(0,to), 
                arr[from], 
                arr.filter((x,i) => i != from).slice(to)) 
            : to > from
                ? [].concat(
                    arr.slice(0, from), 
                    arr.slice(from + 1, to + 1), 
                    arr[from], 
                    arr.slice(to + 1))
                : arr}
    

    【讨论】:

      【解决方案3】:

      在您的示例中,因为是string 的数组,我们可以使用排名对象对字符串数组重新排序:

      let rank =  { 'a': 0, 'b': 1, 'c': 2, 'd': 0.5, 'e': 4 };
      arr.sort( (i, j) => rank[i] - rank[j] );
      

      我们可以使用这种方法编写一个move 函数来处理字符串数组:

      function stringArrayMove(arr, from, to)
      {
        let rank = arr.reduce( (p, c, i) => ( p[c] = i, p ), ({ }) );
        // rank = { 'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4 }
        rank[arr[from]] = to - 0.5;
        // rank = { 'a': 0, 'b': 1, 'c': 2, 'd': 1.5, 'e': 4 }
        arr.sort( (i, j) => rank[i] - rank[j] );
        // arr = [ 'a', 'd', 'b', 'c', 'e' ];
      }
      
      let arr = [ 'a', 'b', 'c', 'd', 'e' ];
      stringArrayMove(arr, 3, 1);
      console.log( JSON.stringify(arr) );

      然而,如果我们想要排序的是一个对象数组,我们可以将排名作为每个对象的新属性引入,即

      let arr = [ { value: 'a', rank: 0 },
                  { value: 'b', rank: 1 },
                  { value: 'c', rank: 2 },
                  { value: 'd', rank: 0.5 },
                  { value: 'e', rank: 4 } ];
      arr.sort( (i, j) => i['rank'] - j['rank'] );
      

      我们可以使用Symbol 隐藏此属性的可见性,即它不会显示在JSON.stringify 中。我们可以在objectArrayMove 函数中概括这一点:

      function objectArrayMove(arr, from, to) {
        let rank = Symbol("rank");
        arr.forEach( (item, i) => item[rank] = i );
        arr[from][rank] = to - 0.5;
        arr.sort( (i, j) => i[rank] - j[rank]);
      }
      let arr = [ { value: 'a' }, { value: 'b' }, { value: 'c' }, { value: 'd' }, { value: 'e' } ];
      console.log( 'array before move: ', JSON.stringify( arr ) );
      // array before move:  [{"value":"a"},{"value":"b"},{"value":"c"},{"value":"d"},{"value":"e"}]
      objectArrayMove(arr, 3, 1);
      console.log( 'array after move: ', JSON.stringify( arr ) );
      // array after move:  [{"value":"a"},{"value":"d"},{"value":"b"},{"value":"c"},{"value":"e"}]

      【讨论】:

        【解决方案4】:

        如果对象是嵌套的:

          let array = ['a', 'b', 'c', 'd', 'e'];
          let existingElement = JSON.parse(JSON.stringify(array[3]));
          array.splice(1, 0, existingElement);
          array.splice(4, 1);
          console.log(array)
        

        【讨论】:

          猜你喜欢
          • 2023-03-29
          • 2017-11-04
          • 2017-10-19
          • 2013-06-28
          • 2018-10-15
          • 1970-01-01
          • 2023-01-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多