2012-02-08 47 views
0

我試圖編寫一些JavaScript,它接受一個數組的條目並將其排序。它不像它應該編譯。似乎只運行一次for循環。我錯過了什麼?JavaScript數組混排器無法正常工作

//random number between 1 and num 
function randInt(num){ 
    return Math.floor(num*Math.random()+1); 
} 

//shuffles deck (array) of any size 
function shuffle(array){ 
    var newArray = new Array(); 
    var n = array.length; 
    for(i=0; i<n; i++){ 
     var entry = randInt(array.length) - 1; 
     newArray[i] = array[entry]; //assigns random entry in initial array to  new array 
      array = array.splice(entry, 1); //removes the entry that was stored into newArray 
    } 
    array = newArray; 
} 
+2

宣告 「我」 與'var'!這也是一個非常浪費的洗牌方式,即使你設法讓它運作起來。查看wikipedia上的[Fisher-Yates shuffle article](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)。沒有理由調用'.slice()'。 – Pointy 2012-02-08 22:49:11

+0

並在循環之外聲明'var entry' ..哦,到底是什麼,只要運行JSLint man:P – Halcyon 2012-02-08 22:51:38

+0

@FritsvanCampen:我不同意,'entry'不在循環之外使用,JS沒有多個var語句的問題。確實,所有變量的作用範圍都在函數中,但我更願意將它保留在循環中,這就告訴下一個開發人員它只能用在循環中。 – 2012-02-08 23:18:04

回答

4
  • array.splice修改array和返回被刪除的項目(S)。你想放棄的元素,所以才做這個,而不是覆蓋array
array.splice(entry, 1); 
  • + 1randInt和做- 1事後看來superflouous。
  • 使用var i = 0(儘管看看我的最後一點)。
  • 使用[]而不是new Array(),因爲後者通常不被使用。
  • 返回新的數組,而不是覆蓋array
return newArray; 
  • 您修改array所以你不能循環達到n了,因爲長度變爲1每次少。您可能需要while(array.length > 0) { ... }而不是for循環。
+0

非常快速的分析數量令人印象深刻 – mrtsherman 2012-02-08 22:53:00

+0

唉!當然。如果我沒有認識到我面前缺乏變數,我感到很愚蠢。 randInt用在我需要一個正整數的地方,否則我會做這個調整。至於你的最後一點,我設置了數組的初始長度來規避這個問題,但我同意你的while循環更清晰。謝謝。 – amdilley 2012-02-08 22:57:10

0

不需要重新發明輪子(在這種情況下是洗牌)。

function shuffle(o){ 
    for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); 
    return o; 
} 

http://snippets.dzone.com/posts/show/849

+0

這似乎從發佈的問題[這裏](http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete的.html)。 – pimvdb 2012-02-08 22:52:01

0

爲什麼不直接在自定義函數中使用array.sort?

function shuffle(array) { 
    array.sort(function(a, b) { 
     return (Math.random() < 0.5) ? 1 : -1; 
    }); 
} 
+1

這是一個糟糕的洗牌方式。 – Pointy 2012-02-08 22:54:29

+0

...更多:可怕的原因有幾個。你不知道排序會做什麼,所以很難說每個元素是否一定會被排序。由於函數調用,它很昂貴。另外,因爲任何兩個元素的比較在不止一次比較時都會有所不同,所以排序可能會變得非常混亂,並且可能不會終止。 – Pointy 2012-02-08 23:04:23

3

您在這裏的根本問題是,彷彿是JavaScript的一個呼叫通過參考語言的代碼編寫。不是;它是按價值劃撥的。因此,函數的最後一行在語法上是正確的,但在功能上是無用的。

這裏的費雪耶茨洗牌:

function fyShuffle(a) { 
    if (a.length < 2) return; 
    for (var i = a.length; --i >= 1;) { 
    var j = ~~(Math.random() * (i + 1)), tmp; 
    tmp = a[j]; 
    a[j] = a[i]; 
    a[i] = tmp; 
    } 
} 
0
Array.prototype.shuffle= function(){ 
    var i, L= this.length; 
    while(--L){ 
     i= Math.floor(Math.random()*L); 
     this[L]= this.splice(i, 1, this[L]) 
    } 
    return this; 
} 

很難說,如果使用拼接比直接勘定更快

Array.prototype.shuffle= function(){ 
    var i, temp, L= this.length; 
    while(--L){ 
     i= Math.floor(Math.random()*L); 
     temp= this[i]; 
     this[i]= this[L]; 
     this[L]= temp; 
    } 
    return this; 
}