如何使用 Javascript 处理文本的每个字母?

IT技术 javascript string
2021-01-23 08:15:27

我想提醒字符串的每个字母,但我不确定如何执行此操作。

所以,如果我有:

var str = 'This is my string';

我希望能够分别提醒This等。这只是我正在研究的一个想法的开始,但我需要知道如何分别处理每个字母。

我想我可能需要在测试字符串的长度后使用 split 函数。

我怎样才能做到这一点?

6个回答

如果警报的顺序很重要,请使用以下命令:

for (var i = 0; i < str.length; i++) {
  alert(str.charAt(i));
}

或者这个:(另见这个答案

 for (var i = 0; i < str.length; i++) {
   alert(str[i]);
 }

如果警报的顺序无关紧要,请使用以下命令:

var i = str.length;
while (i--) {
  alert(str.charAt(i));
}

或者这个:(另见这个答案

 var i = str.length;
while (i--) {
  alert(str[i]);
}

我发现很难相信任何现代 JS 编译器会在循环内没有修改字符串时重新计算长度。在所有其他语言中,我很乐意在 for 循环的 test 子句中进行长度检查,假设编译器最了解并相应地对其进行优化。
2021-03-13 08:15:27
[]IE < 9 不支持使用来获取特定位置的字符
2021-03-19 08:15:27
@Dagmar:Javascript 不使用 UTF-8,它使用 UTF-16(或 UCS-2,取决于浏览器)。每个单个字符都可以表示为 UTF-8 或 UTF-16,但没有这个问题。唯一有问题的是需要 UTF-16 中的四个字节而不是两个字节的那些。💩 是 UTF-16 中需要四个字节的字符。查找更多信息的关键术语是“星体平面”、“非 BMP”和“代理对”。
2021-03-19 08:15:27
如另一个答案所述,您可以使用 str.charAt(i) 代替 [] 的。有关为什么应该使用 charAt 与 [] 的更多信息,请参阅string.charAt(x) 或 string[x]
2021-03-24 08:15:27
@Dagmar:Java 和 Javascript 都有共同的 UTF-16(以前称为 UCS-)。使用它的第三个主要平台是 Windows。Unix、MacOS 和互联网协议使用 UTF-8。charAt是 UCS-2 时代遗留下来的,当时没有代理对,为了解决这个问题,一个新函数codepointAt被添加到 JavaScript 中,以正确处理我们友好的便便堆。我相信Java也有。
2021-03-24 08:15:27

这可能不仅仅是解决了。只想提供另一个简单的解决方案:

var text = 'uololooo';

// With ES6
[...text].forEach(c => console.log(c))

// With the `of` operator
for (const c of text) {
    console.log(c)
}

// With ES5
for (var x = 0, c=''; c = text.charAt(x); x++) { 
    console.log(c); 
}

// ES5 without the for loop:
text.split('').forEach(function(c) {
    console.log(c);
});
不,不能。forEach()将索引和数组作为第二个和第三个参数传递。我宁愿不记录那个..
2021-03-17 08:15:27
最后一个例子可以简单地是 [...text].forEach(console.log)
2021-03-19 08:15:27
其中,只有前两个将遍历字符串的字符。其余的通过 UTF-16 代码单元进行迭代。例如 trytext = "\ud835\udcaf\ud835\udcae\ud835\udca9"这个字符串中有 3 个 unicode 字符,但有 6 个代码单元。
2021-03-20 08:15:27
请注意,扩展运算符(第一个示例)和拆分调用(最后一个示例)都将创建一个新数组。这通常不会成为问题,但对于大字符串或频繁使用来说可能代价高昂。
2021-03-28 08:15:27
关于什么 for (let c of [...text]) { console.log(c) }
2021-04-06 08:15:27

如何处理文本的每个字母(带基准)

https://jsperf.com/str-for-in-of-foreach-map-2

为了

经典,迄今为止性能最高的一款如果您打算在性能关键算法中使用它,或者它需要与浏览器版本的最大兼容性,则应该使用它。

for (var i = 0; i < str.length; i++) {
  console.info(str[i]);
}

对于...的

for...of是新的ES6迭代器。大多数现代浏览器都支持。它在视觉上更具吸引力,并且不太容易出现打字错误。如果您打算在生产应用程序中使用这个,您可能应该使用像Babel这样的转译器

let result = '';
for (let letter of str) {
  result += letter;
}

为每个

功能方法。Airbnb 批准这样做的最大缺点是split(), 它会创建一个新数组来存储字符串的每个单独的字母。

为什么?这强制执行我们的不可变规则。处理返回值的纯函数比副作用更容易推理。

// ES6 version.
let result = '';
str.split('').forEach(letter => {
  result += letter;
});

或者

var result = '';
str.split('').forEach(function(letter) {
  result += letter;
});

以下是我不喜欢的。

因为...在

与 for...of 不同,您得到的是字母索引而不是字母。它的表现非常糟糕。

var result = '';
for (var letterIndex in str) {
  result += str[letterIndex];
}

地图

函数方法,这很好。但是,地图并不打算用于此目的。当需要更改数组内的值时应该使用它,但事实并非如此。

// ES6 version.
var result = '';
str.split('').map(letter => {
  result += letter;
});

或者

let result = '';
str.split('').map(function(letter) {
  result += letter;
});
在我的机器上,经典for循环实际上是第二慢的,for...of而是最快的(大约是 的三倍for)。
2021-03-20 08:15:27
@JohnMontgomery 我不希望你做任何事情。只是提醒未来的读者,您的结果与答案不同。我个人想知道哪些结果适用于今天 2020 年的浏览器,尽管 2018 年不是很久以前。哪个链接失效了?
2021-03-25 08:15:27
@johnywhy 顶部包含所有实际测试的链接为我返回 404。
2021-03-31 08:15:27
@johnywhy 那是两年前,链接已经失效,所以我不确定你希望我如何捍卫我当时得到的结果。设置新的基准现在与 zurfyx 的结论一致,for循环稍微快一点。
2021-04-01 08:15:27
标杆在哪里?最快的解决方案是什么?
2021-04-06 08:15:27

纯 javascript 中的一种可能解决方案:

for (var x = 0; x < str.length; x++)
{
    var c = str.charAt(x);
    alert(c);
}
此外, str.length 应该存储在一个变量中,这样它就不必一直被访问。
2021-03-26 08:15:27
@EliGrey 将长度放在变量中真的那么重要吗?当这比使用更少的代码行更可取时,您是否有基准测试?
2021-03-29 08:15:27
@paul_sns 同样有趣的是,Chrome 在大约 2% 的时间内进行了相同的测试(~5ms vs ~0.0997ms),并且两个版本都给出了相同的时间,所以看起来 Edge 没有优化。
2021-04-03 08:15:27
使用 var x = 0 和 var c = str.charAt(x) 可能会更好。
2021-04-05 08:15:27
for (var x = 0, c=''; c = "💩💩💩💩💩💩💩💩".charAt(x); x++) { console.log(c); }
2021-04-10 08:15:27

这里的大多数(如果不是全部)答案都是错误的,因为只要字符串中有 Unicode BMP(基本多语言平面)之外的字符,它们就会中断这意味着所有表情符号都将被破坏

JavaScript对所有字符串使用UTF- 16 Unicode。在 UTF-16 中,超出 BMP 的字符由两部分组成,称为“代理 ”,此处的大多数答案将单独处理此类对的每个部分,而不是将其作为单个字符处理。

至少自 2016 年以来,现代 JavaScript 的一种方法是使用新的String iterator这是(几乎)直接来自 MDN 的示例:

var string = 'A\uD835\uDC68B\uD835\uDC69C\uD835\uDC6A';

for (var v of string) {
  alert(v);
}
// "A"
// "\uD835\uDC68"
// "B"
// "\uD835\uDC69"
// "C"
// "\uD835\uDC6A"

有关在考虑代理对的同时将字符串拆分为字符的现代解决方案,请参阅:stackoverflow.com/a/42596897/527702
2021-04-12 08:15:27