-
Notifications
You must be signed in to change notification settings - Fork 6
Open
Description
数组是一种由有序的元素序列组成的集合,每个元素在数组中有一个位置,以数字表示,称为索引。
那么如何对数组项的位置进行移动操作?如何实现两个数组项的位置互换?
思路:
数组项的位置移动本质上是相邻数组项的位置互换(数组边界的情况除外),例如下面的数组:
['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
Labels
No labels