Javascript返回数组中“匹配”数组的位置索引

时间:2012-07-02 19:52:15

标签: javascript arrays

是否有另一种更快的方法可以在另一个数组(多个值匹配)中返回数组部分的位置/索引?它在我的寻路算法中被称为很多,所以可以尽可能快地进行。

我目前的职能是:

// Haystack can be e.g. [[0,1,278.9],[4,4,22.1212]]

function coordinate_location_in_array(needle,haystack){
    for(n in haystack){
        if(haystack[n][0]==needle[0] && haystack[n][1]==needle[1]) return n;
    }
    return false;
}

// Needle of [0,1]: returns 0
// Needle of [4,4]: returns 1
// Needle of [6,7]: returns false

编辑:

我一直在搞乱一点,并提出了一个(相当可怕的)基于字符串操作的方法(从而避免了昂贵的for循环)。我认为它仍然稍慢。有人可以对这些方法进行基准测试吗?

function coordinate_location_in_array(needle,haystack) {
    var str1 = ':' + haystack.join(':');
    var str2 = str1.replace(':'+needle[0]+','+needle[1],'*').split('*')[0]; 
    if(str2.length == str1.length) return false;
    var preceedingElements = str2.match(/:/g);
    return preceedingElements!=null?preceedingElements.length:0;
}

也许通过一些改进,第二种方法可能会带来一些性能提升?

编辑2:

Bench使用jsperf.com标记了所有3种描述的方法(初始方法最快): http://jsperf.com/finding-matched-array-within-array/3

编辑3:

刚刚用for(..in..)循环取代了for(..;..;..)循环(因为我知道haystack数组永远不会有“空白”)并且性能似乎有了显着提升:

function coordinate_location_in_array(needle,haystack){
    for(var n=0;n<haystack.length;n++){
        if(haystack[n][0]==needle[0] && haystack[n][1]==needle[1]) return n;
    }
    return false;
}

我已经更新了jsperf页面以包含这个最新方法。

4 个答案:

答案 0 :(得分:2)

如果“haystack”没有排序,那么就没有办法让它更快。不知道集合中的元素是如何排序的,因此本质上是从线性中找到某些东西,因为你只需要检查每个东西。

如果你一遍又一遍地在同一个“草堆”上使用这个功能,你可以对集合进行排序,并使用排序来更快地找到“针”(查找不同的排序和搜索算法以找到一个最符合您需求的,例如使用二进制搜索在干草堆分类后找到“针”。)

答案 1 :(得分:0)

我不知道它是否更快,但你可以做类似的事情:

[1,2,3,4].slice(0,2).toString() == [1,2].toString()
在你的情况下,它将是:

function coordinate_location_in_array(needle,haystack){
for(n in haystack){
    if(haystack[n].slice(0,2).toString() == needle.toString()) return n
}
return false;

}

还发现这篇文章,其中包括JS数组的比较:compare-two-arrays-javascript-associative

干杯 悠闲

答案 2 :(得分:0)

使用for(..;..;..)循环而不是for(..in..)循环产生了最大的不同。

(参见问题末尾的编辑3)

答案 3 :(得分:0)

在我看来,这只是一个子字符串搜索,但是数字而不是字符是字符串的组成部分。因此,Boyer-Moore可能适用,特别是如果您的针头和干草堆变大。