关于处理拼接时的问题(包括Move an array element from one array position to another),我读了几个关于问题的答案,但我无法解决我的问题。
我正在尝试以特定模式重新排序数组。我们假设模式是所有负数应该是数组的左,所有 postive 数字应该是正确的数组。如果有的话,负数和正数应该用零分隔。 维护订单非常重要
Sample Input = [3,0,2,-1,0,-3]
Desired Output = [-1,-3,0,0,3,2]
这是我写的代码
function reorderArray(inputArray) {
origLength = inputArray.length
var indexZero = -1;
for (var i = 0; i < origLength; i++) {
if (inputArray[i] > 0) {
inputArray.push(inputArray[i]);
inputArray.splice(i, 1);
} else if (indexZero == -1 && inputArray[i] == 0) {
indexZero = i;
} else if (indexZero != -1 && inputArray[i] < 0) {
inputArray.splice(indexZero, 0, inputArray.splice(i, 1))
indexZero++;
}
}
alert(inputArray);
}
我在第一步遇到问题,我试图在数组后面移动所有正数,因为重新索引。我无法从最后一个索引开始,因为这意味着丢失订单而我不能使用 i - ,因为它会无限运行。
任何有关如何使我的代码工作的帮助将不胜感激。另外,如果有一种比splice更有效的替代方案,那也是受欢迎的。
感谢。
答案 0 :(得分:2)
var input = [3,0,2,-1,0,-3];
var copy = input.slice(0); // you need an original array copy since you need to
// refer to it to maintain the original order
input.sort(function(a, b) {
var sign_a = Math.sign(a),
sign_b = Math.sign(b);
if (sign_a != sign_b) {
return sign_a - sign_b;
}
return copy.indexOf(a) - copy.indexOf(b);
});
console.log(input);
JSFiddle:http://jsfiddle.net/w2g195fy/2/
因此,您首先按符号比较数字,然后通过比较原始数组中的位置来保证排序的稳定性。后者重要,因为Array.prototype.sort()
无法保证保持稳定。
另一个重要说明:此特定实现的复杂性(从比较数量的角度来看)是O(N^2 * logN)
,如果您有大型原始数组,这可能是不可接受的。
另一个重要提示:如果您的输入数组有重复值,它将不起作用。
这是一个天真的实现,可以使用重复项:
var input = [1, -1, 2, 0, -2, 3, 0, -3, -4, 4, 0];
var groups = input.reduce(function(result, item) {
result[Math.sign(item)].push(item);
return result;
}, {'-1': [], 0: [], 1: []});
var result = groups['-1'].concat(groups[0]).concat(groups[1]);
console.log(result)
这是我能想到的最有效的(从内存和比较数量的角度来看 - 它是O(N)
)解决方案:
var input = [1, -4, 2, 0, -2, 3, 0, -3, -4, 4, 0];
var result = [];
for (var sign = -1, len = input.length; sign <= 1; ++sign) {
for (var i = 0; i < len; ++i) {
if (Math.sign(input[i]) == sign) {
result.push(input[i]);
}
}
}
console.log(result);
答案 1 :(得分:1)
使用sort
执行此操作的另一种方法:
[3,0,2,-1,0,-3].map(function () { return arguments; }).sort(function (a, b) {
var aNum = a[0],
bNum = b[0],
bothNegative = aNum < 0 && aNum < 0,
bothPositive = aNum > 0 && bNum > 0;
if (bothNegative || bothPositive) return a[1] - b[1];
return aNum - bNum;
}).map(function (arr) { return arr[0]; });
保留初始订单,但现在它们分为3组。否定,零和积极。
答案 2 :(得分:0)
这也可以是一个解决方案:
var input = [3,0,2,-1,0,-3].join('+');
var output = input.match(/-\d+/g).concat( input.match(/0/g) ).concat( input.match(/(^|\+)[1-9]\d*/g) ).map(parseFloat);
由于最后一个数组sort
(可以省略),它比map
慢,但想法可能有用。