2016-09-10 24 views
0

我正在嘗試交換這些數組內的數據。快速高效地切換數組元素

我的數據看起來像這樣。在生產過程中,這個陣列可以並且將會大幾倍。

var data = [ 
    [13.418946862220764, 52.50055852688439], 
    [13.419011235237122, 52.50113000479732], 
    [13.419756889343262, 52.50171780290061], 
    [13.419885635375975, 52.50237416816131], 
    [13.420631289482117, 52.50294888790448] 
] 

目前我的切換代碼如下所示。

var temp; 

for(var i = 0;i < data.length;i++) { 
    temp = array[i][0]; 
    array[i][0] = array[i][1]; 
    array[i][1] = temp; 
} 

我試圖找出是,如果您這樣做的最有效的方式和/或如果任何改進都是可能的。

請理解,即使稍有改善也很重要。

+1

您的切換代碼並不實際切換元素,而只是將這些子陣列的第二個元素放入第一個元素中。 – Matt

+0

你可以嘗試緩存'var row = array [i];' – Xotic750

+1

'data'和'temp'的預期結果是什麼?_「我想弄明白的是,如果這是實現這一目標的最有效方式」_「最高效」的含義是什麼?完成該過程所需的最少時間? – guest271314

回答

3

我會用更多的功能的方法:

var switched = data.map(function (arr) { 
    return [arr[1], arr[0]]; 
}); 

如果使用ES2015,你甚至可以做,在一個行:

const switched = data.map((arr) => [arr[1], arr[0]]); 
+2

解構時更短:'data.map(([[a,b])=> [b,a])' –

+0

這將通過創建一個新陣列來增加內存佔用空間 –

+0

@RegisPortalez它一點也不清楚將。你會建議什麼樣的新陣列?參數解構'[a,b]'不會創建一個新的數組;它只是從參數中提取'a'和'b'。 –

0

如果你想堅持一個循環:

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

你的代碼看起來非常好,你不需要任何進一步的「優化」。

與往常一樣,基準總是要找出誰是更快的好辦法:

var arr = (function() { 
 
    var res = []; 
 
    for(var i = 0; i < 100000; ++i) { 
 
     res[i] = [Math.random(), Math.random()]; 
 
    } 
 
    return res; 
 
}()); 
 

 
var swap_in_place = function() { 
 
    for(var i = 0; i < arr.length; ++i) { 
 
     var tmp = arr[i][0]; 
 
     arr[i][0] = arr[i][1]; 
 
     arr[i][1] = tmp; 
 
    } 
 
}; 
 

 

 
var swap_map = function() { 
 
    arr = arr.map(function(elem) {return [elem[1], elem[0]]; }); 
 
}; 
 

 
var runBench = function(name, f) { 
 
    var start = new Date().getTime(); 
 
    for(var i = 0; i < 50; ++i) { 
 
     f(); 
 
    } 
 
    var stop = new Date().getTime(); 
 
    console.log(name + " took: " + (stop - start)); 
 
}; 
 

 

 
runBench("in_place", swap_in_place); 
 
runBench("map", swap_map);

在我的Firefox最新版本(窗口10 64),我得到(相當一致) 16代表地圖版本,vs 350代表地圖版本,這意味着通過使用地圖而不是您自己的版本,您可以獲得20倍速下降

你可能認爲這是由於這個代碼片段嵌入在iframe等等中,所以我將它運行在構建於V8之上的節點(4.5.0)中,並且我得到了相同的結果結果:

enter image description here

我認爲,抖動不能足夠的智慧妥善內嵌的地圖版本的功能,或者推斷它無副作用相同的內存進行操作。 Thefore,跳動到超過其分配一個完整的新的數組來存儲中間結果,然後循環與一個函數調用(意味着寄存器保存/恢復在每次迭代失速),然後或者:

  • 複製回整個數據到arr
  • 移動引用(可能發生了什麼),但垃圾收集器必須收集整個臨時數組。

映射函數也可能觸發重新分配臨時值,這非常昂貴。