这是我的第一个想法。
function isSubsetOf(elements, set) {
var i, l = elements.length, pos;
set = set.split('');
for (i = 0; i < l; i += 1) {
pos = set.indexOf(elements.charAt(i));
if (pos == -1) return false;
set.splice(pos, 1);
}
return true;
}
/*-- Algorithm: --*/
// for each character in *elements*:
// remove that character from an array of *set*'s characters
// (and if not found, return false).
但是,我不知道 IE 没有Array.indexOf
. 这使得它在 IE 上的性能方面是一个可怕的失败者,并且添加了符合标准的indexOf
功能Array.prototype
。然而,令我惊讶的是,它只是用 Chrome尖叫,这显然是一台卑鄙的拼接机器。
我的第二个想法比我的第一个想法好很多,但并不比页面上的其他想法好很多。
function isSubsetOf2(elements, set) {
var i, l, counts = {};
for (i = 0, l = set.length; i < l; i += 1) {
char = set.charAt(i);
counts[char] = (counts[char] || 0) + 1;
}
for (i = 0, l = elements.length; i < l; i += 1) {
char = elements.charAt(i);
if (!counts[char]) return false;
counts[char] -= 1;
}
return true;
}
/*-- Algorithm: --*/
// For each character in *set*:
// increment its count in an object "map".
// For each character in *elements*
// decrement its count in an object map
// (and if < 0 or doesn't exist, return false)
因此,最后,我的第三个想法在 Firefox 中是最快的,并且是一个很好的全能竞争者,尽管不同的浏览器针对不同的功能显示完全不同的速度配置文件。
function isSubsetOf3(elements, sets) {
var e, s, el = elements.length, sl = sets.length;
elements = elements.split('').sort();
sets = sets.split('').sort();
for (e = 0, s = 0; e < el; e += 1, s += 1) {
while (s < sl && sets[s] < elements[e]) { s += 1; }
if (s == sl || sets[s] > elements[e]) { return false };
}
return true;
}
/*-- Algorithm: --*/
// Sort arrays of the characters in *elements* and *set*.
// Do a logical "merge join" (cool!) and:
// if no match is found, return false
// MERGE JOIN:
// For each character in the *elements* array ("left" input)
// Consume one matching character from *set* ("right" input)
// (skipping matches that are less than the character)
// And if *set* runs out of characters or is higher than *element*, return false
如果输入已排序,则合并连接速度很快。显然,在浏览器中对两个数组进行排序比对每个字符串执行多个正则表达式操作要快。
编辑:我刚刚意识到我的想法 #2 基本上是 Kolink 算法的副本。但是,我的功能具有一致的性能优势。在分析它们的差异时可能会发现一些有趣的结果。
另外,我发现在#2 中,我不应该counts[char] -= 1;
向上移动一条线,但我不想破坏我已经在 jsperf 获得的性能结果。所以我要离开它,因为它不会不公平地扭曲结果,因为它只会损害函数的性能。
在 jsperf 自己做速度测试!