2010-09-23 60 views

回答

5

你可以使用下面的循環來完成它。我已經包含整個頁面用於測試目的。

<html> 
    <body> 
     <script type="text/javascript"> 
      var i; var y = 0; var val = 321; var zones = [0,150,300,400,600,800]; 
      for (i = 0; i < zones.length; i++) 
       if (val >= zones[i]) 
        y = i; 
      document.write("Value " + val + " is at position " + y); 
     </script> 
    </body> 
</html> 

使用各種測試數據:

Value -99 is at position 0 
Value 0 is at position 0 
Value 149 is at position 0 
Value 150 is at position 1 
Value 321 is at position 2 
Value 521 is at position 3 
Value 799 is at position 4 
Value 800 is at position 5 
Value 999 is at position 5 
+0

謝謝,這個作品很棒! – John 2010-09-23 05:36:47

+0

@John如果你的表現很重要,那麼你可以考慮使用二進制搜索方法。 – ErikE 2010-09-23 05:45:18

+2

一些特定於JS的註釋:'var'在JavaScript中並不是真正的可選項,在這個示例中似乎沒有任何區別,因爲所有標識符都是全局標識符,但不推薦使用,因爲例如,如果將上面的代碼放入函數中,標識符仍然是全局的,而且,新的ECMAScript 5 [嚴格模式](http://j.mp/dzg47V)不允許對未聲明的標識符進行分配。另外,'for-in'語句可能看起來類似於在C#,PHP,Perl等中可以說'foreach',但不是,for-in的目的是*枚舉* object屬性,枚舉順序不保證... – CMS 2010-09-23 06:02:31

0

是否按升序排列數字數組?如果是,那麼你有兩個選擇。如果數組的大小相對較小,只需循環遍歷它,然後找到適當的區域。否則實現二進制搜索(更快)。

+0

是的,它是按升序排列。陣列的大小很小,但將來可能很大。謝謝,我會試一試。 – John 2010-09-23 05:27:44

3

如果陣列是非常大的,檢查每個元素將是緩慢的。在這種情況下,二分查找可能很好。下面是一些示例代碼(未經測試,但經過深思熟慮的,因爲我可以在晚上的這個時候這樣做):

function checkZone(mouseX) { 
    var low = 0, high = zones.length, i; 
    if (mouseX >= zones[high]) { 
     low = high 
    } 
    while (high - low > 1) { 
     i = low + Math.floor((high - low)/2); 
     if (mouseX >= zones[i]) { 
     low = i; 
     } else { 
     high = i; 
     } 
    } 
    return zones[low]; 
} 

注意:我想張貼這大約15分鐘前,但SO吃了我的答案和我不得不重做大部分。

+0

這隻有在數組很大時纔有用,否則迭代每個元素會更快,直到找到爲止,因爲評估的條件較少。 – vol7ron 2010-09-23 06:20:11

+1

@vol這**是**我說的第一句話在我的帖子裏。不過謝謝你的加強。我猜。 :) – ErikE 2010-09-23 06:25:40

+1

是的,我說的第一部分加強。第二部分我加了一點點解釋。好的算法結合了這兩者。它從二進制開始,然後一旦它達到一定的數字,就切換到字面枚舉比較。 – vol7ron 2010-09-23 06:43:01

-1

這應該是更好,更快:

console.clear(); 

    var zones = [800, 400, 150, 0, 300, 600];    // unsorted array 
    zones.sort();           // sort for function comparison 
    console.log(zones); 

    function checkZone(mouseX) { 
     for(var i = (zones.length-1); mouseX < zones[i--];){ } 
     return ++i; 
    } 


    // perform 25 tests with random mouseX values 0-1000 
    for (var rnd=1,runs=25; runs-- && (rnd=Math.floor(Math.random()*1000))>=0;){ 
     console.log((25-runs) + ". " 
        + "mouseX:" + rnd + " , " 
        + "index:" + checkZone(rnd)   // checkZone(number) is all that's really needed 
       ); 
    } 

for循環的功能從搜索最後一個數組值開始的數組。一旦參數不再小於數組值,循環退出並且函數返回該元素。我們必須向返回變量添加一個,因爲當循環條件失敗時,循環不會返回1。

如果您對console.log感覺不舒服,您可以用document.writealert替換它。完成測試後,所需的全部是已排序的數組,函數和函數調用。你可以放棄測試循環和所有隨機數jibber-jabber。

輸出示例:

[0, 150, 300, 400, 600, 800] 
    1. mouseX:458 , index:3 
    2. mouseX:17 , index:0 
    3. mouseX:377 , index:2 
    4. mouseX:253 , index:1 
    5. mouseX:446 , index:3 
    6. mouseX:764 , index:4 
    7. mouseX:619 , index:4 
    8. mouseX:653 , index:4 
    9. mouseX:337 , index:2 
    10. mouseX:396 , index:2 
    11. mouseX:107 , index:0 
    12. mouseX:820 , index:5 
    13. mouseX:850 , index:5 
    14. mouseX:117 , index:0 
    15. mouseX:659 , index:4 
    16. mouseX:393 , index:2 
    17. mouseX:906 , index:5 
    18. mouseX:128 , index:0 
    19. mouseX:435 , index:3 
    20. mouseX:712 , index:4 
    21. mouseX:841 , index:5 
    22. mouseX:259 , index:1 
    23. mouseX:447 , index:3 
    24. mouseX:809 , index:5 
    25. mouseX:892 , index:5 
+1

如果你要通過數組向後退步,最快的JavaScript方法是'while(i--){}',而不是'for'循環。 – ErikE 2010-09-23 06:28:18

+1

這是錯的;不完全錯誤,但並非總是正確的。對於(我;我 - ;){}'是更快/相等。因爲它有所不同,所以更多的是「平等」的一面。查看我的[JSFiddle](http://jsfiddle.net/FZqZN/3409/)作爲我對[最快求和問題]的迴應的一部分(http://stackoverflow.com/questions/3762589/fastest-javascript-summation/ 3762735#3762735)。這個反向for循環與反向while循環基本上是一樣的,但for循環的緩存有其優點,這給它一個次要優勢。 – vol7ron 2010-09-23 06:46:26

+0

看來我被一個不喜歡聽到他們的回答很糟糕的人所迷惑。除了Emtucifor的二進制算法加法,這不適用於問題中給出的小陣列大小,我的解決方案是最好的。 – vol7ron 2010-09-23 07:00:54