JavaScript 有 strcmp() 吗?
有人可以帮我验证一下吗? JavaScript 没有 strcmp() 版本,因此您必须写出如下内容:
( str1 < str2 ) ?
-1 :
( str1 > str2 ? 1 : 0 );
Can anyone verify this for me? JavaScript does not have a version of strcmp(), so you have to write out something like:
( str1 < str2 ) ?
-1 :
( str1 > str2 ? 1 : 0 );
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(8)
泅渡2024-08-06 00:46:59
localeCompare()
很慢,所以如果你不关心“正确”的顺序对于非英文字符串,请尝试原始方法或看起来更简洁的方法:
str1 < str2 ? -1 : +(str1 > str2)
这比我的机器上的 localeCompare()
快一个数量级。
+
确保答案始终是数字而不是布尔值。
﹎☆浅夏丿初晴2024-08-06 00:46:59
来自这篇如何在 JavaScript 中检查两个字符串是否相等文章:
- 一般情况,如果您的字符串仅包含 ASCII 字符,则可以使用
===
运算符来检查它们是否相等。 - 但是,当您的字符串包含包含组合字符的字符(例如
e + ◌́ = é
)时,您首先要对它们进行规范化,然后再比较相等性,如下所示 -s1.normalize() === s2.normalize()
风尘浪孓2024-08-06 00:46:59
所以我陷入了这个兔子洞并编写了一些测试来建立直觉,结果很奇怪。
tldr 看起来像 localeCompare 执行小写
相等运算符则不然。 这会导致“ff”>=“ZZ”,但区域设置比较返回-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);
年华零落成诗2024-08-06 00:46:59
在我的测试中,这比对同一组随机选择的单词使用一对三元语句快大约 10%。
function strcmp( a, b ) {
for( let i=0 ; i<Math.min( a.length, b.length ) ; i++ ) {
const n = a.charCodeAt(i) - b.charCodeAt(i);
if( n ) return n && ( ( n>>31 ) || 1 );
}
const n = a.length - b.length;
return n && ( ( n>>31 ) || 1 );
}
~没有更多了~
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
正如你所指出的,Javascript 没有它。
快速搜索得出:
来自 http://kevin.vanzonneveld.net/techblog/article/ javascript_equivalent_for_phps_strcmp/
当然,如果需要,您可以只添加 localeCompare:
并在任何地方使用
str1.localeCompare(str2)
,而不必担心本地浏览器是否已附带它。 唯一的问题是您必须添加对区域设置
和选项
(如果您关心的话)。Javascript doesn't have it, as you point out.
A quick search came up with:
from http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_strcmp/
Of course, you could just add localeCompare if needed:
And use
str1.localeCompare(str2)
everywhere, without having to worry wether the local browser has shipped with it. The only problem is that you would have to add support forlocales
andoptions
if you care about that.