2010-09-23 74 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