反转二进制数组?

时间:2014-03-28 14:51:49

标签: javascript

反转任意长度二进制数组的最有效方法是什么?即对于数组中的所有0,1,设置1 = 0和0 = 1。

var arr1 = [ 0, 0, 1, 1, 1, 0, ..., 1 ];

6 个答案:

答案 0 :(得分:3)

一般而言,"效率" JavaScript中的问题是一个陷阱,因为不同的引擎在使用不同的东西时效率更高。在解决问题之前进行优化几乎总是浪费时间(无论语言/环境如何),但当优化目标(JavaScript引擎)的性能显着不同时,特别为真轮廓。

一般情况下,根据该警告,我不认为您会发现比缓存长度的简单for循环更有效的方法。< / p>

var arr1 = [ 0, 0, 1, 1, 1, 0, ..., 1 ];
var n, l;
for (n = 0, l = arr1.length; n < l; ++n) {
    arr1[n] = arr1[n] === 0 ? 1 : 0;
}

但是,当您遇到性能问题时再次解决性能问题,然后通过在目标环境中进行测试(在您的应用内或使用http://jsperf.com等工具)来解决这些问题。

答案 1 :(得分:3)

使用二进制操作应该比任何其他方法更快。

var arr1 = [ 0, 0, 1, 1, 1, 0, 1 ];
for (var i = 0; i < arr1.length; i += 1) {
    arr1[i] ^= 1;
}
console.log(arr1);
# [ 1, 1, 0, 0, 0, 1, 0 ]

我们使用Binary XOR 2.它起作用,因为

console.log(1 ^ 1);   // 0
console.log(0 ^ 1);   // 1

答案 2 :(得分:2)

只需映射数组并返回1 00以获取其他任何内容

var arr2 = arr1.map(function(x) { return x === 0 ? 1 : 0; })

FIDDLE

答案 3 :(得分:2)

这是非常低效的,但却是一种有趣的方法来解决问题。

var arr1 = [ 0, 0, 1, 1, 1, 0, 1 ];
var swapped = JSON.parse(JSON.stringify(arr1).replace(/[01]/g, function(x){ return x==0?1:0;}));
  • 将数组转换为字符串
  • String将匹配替换为正则表达式,将字符替换为相反的
  • 将新字符串转换回数组

写成多行:

var arr1 = [ 0, 0, 1, 1, 1, 0, 1 ];
var arrayString = JSON.stringify(arr1);
var flip1and0 = arrayString.replace(/[01]/g, function(x){ return x==0?1:0;});
var swappedArray =  JSON.parse(flip1and0);

答案 4 :(得分:0)

您可以尝试使用for循环。

代码:

var arr1 = [0, 0, 1, 1, 1, 0, 1];

for (var i = 0; i < arr1.length; i++) {
    arr1[i] = 1 - arr1[i]
}

目前二元操作获胜:http://jsperf.com/test-foor-loop

演示:http://jsfiddle.net/IrvinDominin/Kw3e6/

答案 5 :(得分:0)

由于这似乎已经变成了一场竞赛,那么使用Typed Arrays呢?

// Construct an array of length 1024
var length = 1024;
var arr = [];
for (var i = 0; i < length; i++) {
  arr.push(Math.random() > 0.5 ? 1 : 0);
}

var typedLoop = function() {
  var typed = new Uint8Array(arr);
  for (var i = 0; i < typed.length; i++) {
    typed[i] = (typed[i] == 0 ? 1 : 0);
  }
  return arr;
}

var untypedLoop = function() {
  for (var i = 0; i < arr.length; i++) {
    arr[i] = (arr[i] == 0 ? 1 : 0);
  }
  return arr;
}


var withClosure = function() {
  return arr.map(function(x) { return x === 0 ? 1 : 0; });
}

// A time-elapsed function with a lot of repetitions
var reps = 10000;

var time = function(f) {
  var before = new Date().getTime();
  for(var i = 0; i < reps; i++) {
    f();
  }
  console.log(new Date().getTime() - before);
}

一些结果:

time(typedLoop)
212

time(untypedLoop)
6169

time(withClosure)
601 

我认为这真的很有趣。使用类型化数组是最短的。使用具有普通数组的闭包需要3倍的时间。使用for循环是30x。在我的机器上,现在,这个浏览器在这个环境温度和北风吹来的时候发布了。

使用经过的时间根本不是一个很好的衡量指标,但它是一个实际的指示。

显然这根本不重要。你可能不会计算成千上万次的数千次阵列。使用最清晰的代码。但它确实回答了你关于“最有效”的问题(这并不总是最好的)。