Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

第 81 期(数据结构-数组):数组项的互换和移动 #84

Copy link
Copy link
@wingmeng

Description

@wingmeng
Issue body actions

数组是一种由有序的元素序列组成的集合,每个元素在数组中有一个位置,以数字表示,称为索引。
那么如何对数组项的位置进行移动操作?如何实现两个数组项的位置互换?

思路:

数组项的位置移动本质上是相邻数组项的位置互换(数组边界的情况除外),例如下面的数组:

['A', 'B', 'C', 'D'];  // 原数组
['A', 'C', 'B', 'D'];  // 将 C 向前移动一位

我们将 C 向前移动 1 位,本质上就是 B 和 C 互换了位置。那么如何实现位置互换?可以使用临时变量存储 B,然后从数组中删除 B,再将 B 插入到 C 的后面;或者用 ES6 的结构赋值,临时变量都省了,非常方便。
下面我们来看下具体实现。

/**
 * 交换数组项
 * @param {array} arr - 源数组
 * @param {number} srcIdx - 要交互位置的源数组项索引
 * @param {number} targetIdx - 目标位置索引
 */
function swapArrItem(arr, srcIdx, targetIdx) {
  if (!Array.isArray(arr)) {
    throw Error(`\`${arr}\` is not a array`);
  }

  if (isNaN(srcIdx) || isNaN(targetIdx)) {
    throw Error(`index is not a number`);
  }

  let len = arr.length - 1;

  // 边界情况判断
  srcIdx = srcIdx < 0 ? 0 : srcIdx;
  srcIdx = srcIdx > len ? len : srcIdx;
  targetIdx = targetIdx < 0 ? 0 : targetIdx;
  targetIdx = targetIdx > len ? len : targetIdx;

  arr = [...arr];
  [arr[srcIdx], arr[targetIdx]] = [arr[targetIdx], arr[srcIdx]];  // 解构赋值

  return arr;
}

/**
 * 移动数组项
 * @param {array} arr - 源数组
 * @param {number} idx - 要移动的源数组项索引
 * @param {string} method - 移动方式:
      1. first - 移动到数组最前
      2. last - 移动到数组最后
      3. forward - 向前移动1位
      4. backward - 向后移动1位
 */
function moveArrItem(arr, idx, method) {
  const _toBoundary = (arr1, idx, handle) => {
    let temp = arr1.splice(idx, 1)[0];

    arr1[handle](temp);
    return arr1;
  };

  if (!Array.isArray(arr)) {
    throw Error(`\`${arr}\` is not a array`);
  }

  arr = [...arr];

  switch(method) {
    case 'first':
      return _toBoundary(arr, idx, 'unshift');
    case 'last':
      return _toBoundary(arr, idx, 'push');
    case 'forward':
      return swapArrItem(arr, idx, idx - 1);
    case 'backward':
      return swapArrItem(arr, idx, idx + 1);
    default:
      throw Error(`${method} is not a available parameter`);
  }
}

测试用例:

let testArr = [0, 1, 2, 3, 4, 5];

console.log('原数组', testArr);
console.log('交换下标1和2项的位置', swapArrItem(testArr, 1, 2));
console.log('交换下标0和3项的位置', swapArrItem(testArr, 0, 3));
console.log('交换下标-5和9项的位置(越界测试)', swapArrItem(testArr, -5, 9));

console.log('将下标2项移动到最前', moveArrItem(testArr, 2, 'first'));
console.log('将下标2项移动到最后', moveArrItem(testArr, 2, 'last'));
console.log('将下标2项向前移动1位', moveArrItem(testArr, 2, 'forward'));
console.log('将下标2项向后移动1位', moveArrItem(testArr, 2, 'backward'));

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.