是否有另一种更快的方法可以在另一个数组(多个值匹配)中返回数组部分的位置/索引?它在我的寻路算法中被称为很多,所以可以尽可能快地进行。
我目前的职能是:
// 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;
}
也许通过一些改进,第二种方法可能会带来一些性能提升?
Bench使用jsperf.com标记了所有3种描述的方法(初始方法最快): http://jsperf.com/finding-matched-array-within-array/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页面以包含这个最新方法。
答案 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可能适用,特别是如果您的针头和干草堆变大。