我不知道这是否是“最佳”方式,但一种直接的方式是使用数组的 findIndex() 方法来定位您要移动的项目,然后使用 splice()方法两次以删除并在您关心的位置重新插入元素。这是一个可能的实现:
function moveToPos<T>(arr: T[], pred: (x: T) => boolean, pos: number) {
const curPos = arr.findIndex(pred);
if (curPos < 0) return;
arr.splice(pos, 0, ...arr.splice(curPos, 1));
}
所以moveToPos() 接受一个数组、一个用于定位元素的谓词以及一个新的元素位置。让我们在一个字符串数组上尝试一下:
const a = ["TRY", "PLO", "OMO", "MNY", "WER", "TQA", "MNB"];
console.log(a.join(",")); // TRY,PLO,OMO,MNY,WER,TQA,MNB
moveToPos(a, s => s === "WER", 0); // move WER to first position
console.log(a.join(",")); // WER,TRY,PLO,OMO,MNY,TQA,MNB
moveToPos(a, s => s === "WER", 1); // move WER to second position
console.log(a.join(",")); // TRY,WER,PLO,OMO,MNY,TQA,MNB
moveToPos(a, s => s === "WER", 2); // move WER to third position
console.log(a.join(",")); // TRY,PLO,WER,OMO,MNY,TQA,MNB
我觉得不错。但也许您只想交换两个元素而不是移动数组?这也是可能的:
function moveToPos<T>(arr: T[], pred: (x: T) => boolean, pos: number) {
pos = Math.max(Math.min(pos, arr.length - 1), 0);
const curPos = arr.findIndex(pred);
if (curPos < 0) return;
[arr[curPos], arr[pos]] = [arr[pos], arr[curPos]]; // destructuring
// or you could do the less tricky way
// const tmp = arr[curPos];
// arr[curPos] = arr[pos];
// arr[pos] = tmp;
}
因此产生不同的结果:
const a = ["TRY", "PLO", "OMO", "MNY", "WER", "TQA", "MNB"];
console.log(a.join(",")); // TRY,PLO,OMO,MNY,WER,TQA,MNB
moveToPos(a, s => s === "WER", 0); // move WER to first position
console.log(a.join(",")); // WER,PLO,OMO,MNY,TRY,TQA,MNB
moveToPos(a, s => s === "WER", 1); // move WER to second position
console.log(a.join(",")); // PLO,WER,OMO,MNY,TRY,TQA,MNB
moveToPos(a, s => s === "WER", 2); // move WER to third position
console.log(a.join(",")); // PLO,OMO,WER,MNY,TRY,TQA,MNB
请注意,存在各种边缘情况:如果您的谓词不匹配任何元素怎么办? (然后什么都没有移动;这就是您想要的吗?)如果您的谓词匹配多个元素怎么办? (然后第一个被移动;这就是你想要的吗?)如果你的新位置在数组之外怎么办(那么无论splice() 做什么都会发生什么)数组中的其余元素会发生什么你没有问过(他们以某种方式移动或交换)所以你应该小心并准确地决定你想要什么,这可能会影响实施。
无论如何,希望对您有所帮助;祝你好运!
更新:如果您只关心将与谓词匹配的元素移动到列表的前面,同时不理会其余元素,并且您想使用数组的 sort() 方法,您可以执行以下操作:
function moveToFront<T>(arr: T[], findPred: (x: T) => boolean) {
arr.sort((x, y) => +findPred(y) - +findPred(x))
}
您通常需要使用谓词来识别要移动的东西,因为相等运算符仅适用于基元和相同的对象引用。无论如何,这会导致:
const a = ["TRY", "PLO", "OMO", "MNY", "WER", "TQA", "MNB"];
console.log(a.join(",")); // TRY,PLO,OMO,MNY,WER,TQA,MNB
moveToFront(a, s => s === "WER");
console.log(a.join(",")); // WER,TRY,PLO,OMO,MNY,TQA,MNB
Playground link to code