有 JavaScript strcmp()吗?

有人能证明吗?JavaScript 没有 strcmp ()的版本,所以您必须写出如下代码:

 ( str1 < str2 ) ?
-1 :
( str1 > str2 ? 1 : 0 );
134479 次浏览

正如你指出的,Javascript 没有这个功能。

我们快速搜索了一下:

function strcmp ( str1, str2 ) {
// http://kevin.vanzonneveld.net
// +   original by: Waldo Malqui Silva
// +      input by: Steve Hilder
// +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// +    revised by: gorthaur
// *     example 1: strcmp( 'waldo', 'owald' );
// *     returns 1: 1
// *     example 2: strcmp( 'owald', 'waldo' );
// *     returns 2: -1


return ( ( str1 == str2 ) ? 0 : ( ( str1 > str2 ) ? 1 : -1 ) );
}

http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_strcmp/

当然,如果需要的话,你可以直接添加 localeCompare:

if (typeof(String.prototype.localeCompare) === 'undefined') {
String.prototype.localeCompare = function(str, locale, options) {
return ((this == str) ? 0 : ((this > str) ? 1 : -1));
};
}

并且在任何地方都使用 str1.localeCompare(str2),而不必担心本地浏览器是否已经附带了 str1.localeCompare(str2)。唯一的问题是,如果您关心这个问题,那么您必须添加对 ABC1和 options的支持。

关于什么

str1.localeCompare(str2)

这个怎么样:

String.prototype.strcmp = function(s) {
if (this < s) return -1;
if (this > s) return 1;
return 0;
}

然后,比较 s1和2:

s1.strcmp(s2)

localeCompare()是缓慢的 ,所以如果你不关心非英文字符串的“正确”排序,试试你原来的方法或者看起来更干净的:

str1 < str2 ? -1 : +(str1 > str2)

这个数量级比我机器上的 abc0还快。

+确保答案始终是数字的而不是布尔的。

var strcmp = new Intl.Collator(undefined, {numeric:true, sensitivity:'base'}).compare;

用法: strcmp(string1, string2)

结果: 1表示 string1较大,0表示相等,-1表示 string2较大。

这比 String.prototype.localeCompare具有更高的性能

此外,numeric:true使它进行逻辑数字比较

如何在 JavaScript 中检查两个字符串是否相等的这篇文章:

  1. 通常,如果字符串只包含 ASCII 字符,则使用 ===运算符检查它们是否相等。
  2. 但是,当字符串包含包含组合字符的字符时(例如。e + ◌́ = é) ,在比较相等性之前首先对它们进行规范化,如下所示 s1.normalize() === s2.normalize()

所以我掉进了这个兔子洞,写了一些测试来建立一个直觉,结果很奇怪。 Tldr 看起来像 localeCompare 执行 a 到小写 相等运算符则不会。这会导致“ ff”为 > = “ ZZ”,但是 locale Compare 返回 -1,因为“ ff”< = ‘ ZZ’

要获得最佳效果,请查看浏览器控制台中的代码日志 ctrl + shift + i

第二剪,它隐藏手测,所以你看到一些随机的。

回家,这对某人有帮助

function stringBench(n, bench, min = 10, len = 10, logDif = false) {
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() *
charactersLength));
}
return result;


}


var a = [];
var b = [];
var pool = {};
let rle = [];
let rlc = [];


let now;
for (let i = 0; i < n; i++) {
pool[i] = (makeid(min + Math.floor(Math.random() *
len))); //10-20ish


}
for (let i = 0; i < bench; i++) {
a[i] = (Math.floor(Math.random() * n));
b[i] = (Math.floor(Math.random() * n));
}


console.log("now testin le vs lc on a pool of", n, " with this many samples ", bench);
now = Date.now();
for (let i = 0; i < bench; i++) {
rlc[i] = pool[a[i]].localeCompare(pool[b[i]]);
}
let lcDelta = Date.now() - now;
console.log("Performed ", bench, "lc localeCompare in ", lcDelta);




now = Date.now();
for (let i = 0; i < bench; i++) {
rle[i] = pool[a[i]] <= pool[b[i]];
}
let leDelta = Date.now() - now;
console.log("Performed ", bench, "le (<=) compares in ", leDelta)


for (let i = 0; i < n; i++) {
pool[i] = (makeid(min + Math.floor(Math.random() *
len))); //10-20ish


}
for (let i = 0; i < bench; i++) {
a[i] = (Math.floor(Math.random() * n));
b[i] = (Math.floor(Math.random() * n));
}




now = Date.now();
for (let i = 0; i < bench; i++) {
rle[i] = pool[a[i]] <= pool[b[i]];
}
let leDelta2 = Date.now() - now;
console.log("Performed ", bench, "le (<=) compares in ", leDelta2)


now = Date.now();
for (let i = 0; i < bench; i++) {
rlc[i] = pool[a[i]].localeCompare(pool[b[i]]);
}
let lcDelta2 = Date.now() - now;
console.log("Performed ", bench, "lc localeCompare in ", lcDelta2);


function testCmp(a, b, log = true) {
let le = a <= b;
let ge = a >= b;
let lc = a.localeCompare(b);
let l = a < b;
let g = a > b;
if (le && ge) console.assert(lc == 0, 'le && ge -> == -> lc == 0,')
if (le) console.assert(lc <= 0, 'le-> lc <= 0')
if (ge) console.assert(lc >= 0, 'ge-> lc >= 0')
if (l) console.assert(lc < 0, 'l=>lc < 0')
if (g) console.assert(lc > 0, 'g-> lc > 0')
if (!log) return;
console.log(`Compare:  ${a} le ${b} `, a <= b);
console.log(`Compare:  ${a} ge ${b}`, a >= b);
console.log(`Compare: ${a} lc ${b}`, a.localeCompare(b));
}


let c = 0
for (let i = 0; i < bench; i++) {
if (rle[i] != rlc[i] <= 0) {
c++;
testCmp(pool[a[i]], pool[b[i]], true);
console.warn(pool[a[i]], ' le != lc <= 0 ', pool[b[i]]);


}




// rlc[i] = pool[a[i]].localeCompare(pool[b[i]]);
}
console.warn(' le != lc  out of bench, num diffs: ', c);




testCmp('ff', 'ff')
testCmp('ff', 'fa')
testCmp('ff', 'fz')
testCmp('ff', 'fff')
testCmp('ff', 'ffa')
testCmp('ff', 'ffz')
testCmp('ff', 'a')
testCmp('ff', 'z')
testCmp('ff', 'f')
testCmp('ff', 'zff')
testCmp('ff', 'aff')
testCmp('ff', 'ZZ')
testCmp('ff', 'AA')
testCmp('FF', 'ZZ')
testCmp('FF', 'ff')
testCmp('FF', 'AA')
testCmp('ff', 'ZZZ')


console.log("Dif le - lc = ", leDelta2 - lcDelta2);


console.log("avg le ms/Mops = ", (leDelta + leDelta2) / (bench / 1000000));
console.log("avg lc ms/Mops = ", (lcDelta + lcDelta2) / (bench / 1000000));




console.log("Dif  - lc = ", leDelta2 - lcDelta2);


};
stringBench(1000, 5000, 1, 3, true);
// stringBench(1000000, 1000000);//nothing is equire
// stringBench(1000, 100000000);
// stringBench(1000000, 100000000, 3, 5);
// stringBench(1000000, 100000000, 15, 20);

function stringBench(n, bench, min = 10, len = 10, logDif = false) {
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() *
charactersLength));
}
return result;




}


var a = [];
var b = [];
var pool = {};
let rle = [];
let rlc = [];


let now;
for (let i = 0; i < n; i++) {
pool[i] = (makeid(min + Math.floor(Math.random() *
len))); //10-20ish


}
for (let i = 0; i < bench; i++) {
a[i] = (Math.floor(Math.random() * n));
b[i] = (Math.floor(Math.random() * n));
}


console.log("now testin le vs lc on a pool of", n, " with this many samples ", bench);
now = Date.now();
for (let i = 0; i < bench; i++) {
rlc[i] = pool[a[i]].localeCompare(pool[b[i]]);
}
let lcDelta = Date.now() - now;
console.log("Performed ", bench, "lc localeCompare in ", lcDelta);




now = Date.now();
for (let i = 0; i < bench; i++) {
rle[i] = pool[a[i]] <= pool[b[i]];
}
let leDelta = Date.now() - now;
console.log("Performed ", bench, "le (<=) compares in ", leDelta)


for (let i = 0; i < n; i++) {
pool[i] = (makeid(min + Math.floor(Math.random() *
len))); //10-20ish


}
for (let i = 0; i < bench; i++) {
a[i] = (Math.floor(Math.random() * n));
b[i] = (Math.floor(Math.random() * n));
}




now = Date.now();
for (let i = 0; i < bench; i++) {
rle[i] = pool[a[i]] <= pool[b[i]];
}
let leDelta2 = Date.now() - now;
console.log("Performed ", bench, "le (<=) compares in ", leDelta2)


now = Date.now();
for (let i = 0; i < bench; i++) {
rlc[i] = pool[a[i]].localeCompare(pool[b[i]]);
}
let lcDelta2 = Date.now() - now;
console.log("Performed ", bench, "lc localeCompare in ", lcDelta2);


function testCmp(a, b, log = true) {
let le = a <= b;
let ge = a >= b;
let lc = a.localeCompare(b);
let l = a < b;
let g = a > b;
if (le && ge) console.assert(lc == 0, 'le && ge -> == -> lc == 0,')
if (le) console.assert(lc <= 0, 'le-> lc <= 0')
if (ge) console.assert(lc >= 0, 'ge-> lc >= 0')
if (l) console.assert(lc < 0, 'l=>lc < 0')
if (g) console.assert(lc > 0, 'g-> lc > 0')
if (!log) return;
console.log(`Compare:  ${a} le ${b} `, a <= b);
console.log(`Compare:  ${a} ge ${b}`, a >= b);
console.log(`Compare: ${a} lc ${b}`, a.localeCompare(b));
}


let c = 0
for (let i = 0; i < bench; i++) {
if (rle[i] != rlc[i] <= 0) {
c++;
testCmp(pool[a[i]], pool[b[i]], true);
console.warn(pool[a[i]], ' le != lc <= 0 ', pool[b[i]]);


}




// rlc[i] = pool[a[i]].localeCompare(pool[b[i]]);
}
console.warn(' le != lc  out of bench, num diffs: ', c);






testCmp('ff', 'fa')
testCmp('ff', 'fz')
testCmp('ff', 'ZZ')






console.log("Dif le - lc = ", leDelta2 - lcDelta2);


console.log("avg le ms/Mops = ", (leDelta + leDelta2) / (bench / 1000000));
console.log("avg lc ms/Mops = ", (lcDelta + lcDelta2) / (bench / 1000000));














console.log("Dif  - lc = ", leDelta2 - lcDelta2);




// for (let i = 0; i < bench; i++) {
//     rlc[i] != rle[i]
//     pool[a[i]].localeCompare(pool[b[i]]);
// }
//
// console.log(makeid(5));
};
stringBench(1000, 5000, 1, 3, true);
// stringBench(1000000, 1000000);//nothing is equire
// stringBench(1000, 100000000);
// stringBench(1000000, 100000000, 3, 5);
// stringBench(1000000, 100000000, 15, 20);