循环
循环方法可以写得更简洁一些
function findFirstDiffPos(a, b) {
var i = 0;
if (a === b) return -1;
while (a[i] === b[i]) i++;
return i;
}
根据jsperf 的说法,这个替代方案比这里的其他方案快 5-20 倍,这不足为奇。
Array#findIndex
由于我们试图找到某个条件成立的索引,这似乎是findIndex 的完美应用:
function findFirstDiffPos(a, b) {
if (a.length < b.length) [a, b] = [b, a];
return [...a].findIndex((chr, i) => chr !== b[i]);
}
(我们需要较长的数组作为我们查找的数组,因此如有必要我们颠倒顺序。我们使用[...a] 将字符串转换为字符数组。)
免责声明:这是一个 ES6 接口,您必须在 IE(但不是 Edge)上进行 polyfill。
这种替代方案比直线循环慢了惊人的 20 倍。
递归
只是为了好玩,这里有一个递归解决方案:
function findFirstDiffPos(a, b) {
return function _iterate([headA, ...tailA], [headB, ...tailB], n) {
return headA !== headB ? n : headA === undefined) ? -1 : _iterate(tailA, tailB, n+1);
}(a.split(''), b.split(''), 0);
}
正则表达式
也在“只是为了好玩”类别中,一个正则表达式解决方案。我们将从一个字符串构造一个/^(a(b(c)?)?)?/ 形式的正则表达式,并将其与另一个字符串进行匹配,并检查匹配的长度。
function make_regexp(str) {
var result = '';
for (var i = str.length-1; i >= 0; i--)
result = '(' + str[i] + result + ')?';
return '^' + result;
}
function findFirstDiffPos(a, b) {
return a === b ? -1 : b.match(make_regexp(a))[0].length;
}
即使我们预编译正则表达式,这仍然比普通的旧循环慢五倍。