我想编写一个函数,从给定的起始索引中在给定数组中找到一个连续的子数组,如果找到,返回数组中的子数组的索引,如果没有找到,则返回-1。这类似于String.indexOf,但是对于数组和子数组,而不是字符串和子数组。
这是我的工作代码:
var find_csa = function (arr, subarr, from_index) {
if (typeof from_index === 'undefined') {
from_index = 0;
}
var i, found, j;
for (i = from_index; i < 1 + (arr.length - subarr.length); ++i) {
found = true;
for (j = 0; j < subarr.length; ++j) {
if (arr[i + j] !== subarr[j]) {
found = false;
break;
}
}
if (found) return i;
}
return -1;
};这些是我的测试和他们的期望值:
console.log(find_csa([1, 2, 3, 4, 5], [2, 3, 4]) === 1);
console.log(find_csa([1, 2, 3, 4, 5], [5]) === 4);
console.log(find_csa([1, 2, 3, 4, 5], [1, 3]) === -1);
console.log(find_csa([1, 2, 3, 4, 5], [42]) === -1);
console.log(find_csa([1, 2, 3, 4, 5], []) === 0);
console.log(find_csa([3, 4, 3, 4, 3, 4], [3, 4, 3], 1) === 2);
console.log(find_csa([6, 6, 6, 7], [6, 6, 7]) === 1);
console.log(find_csa([12, 9, 16, 42, 7, 866, 3], [16, 42, 7, 866]) === 2);我的代码通过了测试,但正如您所看到的,它在内环中使用了一个布尔值found,这正是我从嵌套循环继续外部循环的杂乱无章的方式。有没有一种更干净的书写方式?我查看了Array.prototype.findIndex,但它目前是一种实验技术,所以我不能使用它。我想要一种在大多数浏览器中都能工作的方法。我知道在Mozilla页面上有一个“Poly填充”代码片段,但这比我当前的代码还要长,而且由于函数调用,它会慢一些,所以我宁愿避免它。
这个函数的主要目标是性能(子数组将非常小,因此我认为使用Boyer-Moore字符串搜索算法或试一试有点过分),然后我的次要目标是实现的优雅。考虑到这两个目标,我想知道是否有更好的方法来编写这段代码,或者是否有任何JavaScript特性或函数可以帮助我避免使用found布尔值。
JSFiddle如果它能帮助任何人:http://jsfiddle.net/qc4zxq2p/
发布于 2015-04-03 04:08:27
这和你的一样,只是美化了一点(至少对我的美学而言是这样):
var find_csa = function (arr, subarr, from_index) {
from_index = from_index || 0;
var i, found, j;
var last_check_index = arr.length - subarr.length;
var subarr_length = subarr.length;
position_loop:
for (i = from_index; i <= last_check_index; ++i) {
for (j = 0; j < subarr_length; ++j) {
if (arr[i + j] !== subarr[j]) {
continue position_loop;
}
}
return i;
}
return -1;
};https://stackoverflow.com/questions/29425820
复制相似问题