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

Nic*_*ard 287 javascript string jquery

我想提醒一个字符串的每个字母,但我不确定如何做到这一点.

所以,如果我有:

var str = 'This is my string';
Run Code Online (Sandbox Code Playgroud)

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

我想使用jQuery,并且在考虑字符串的长度后,我可能需要使用split函数.

想法?

Eli*_*rey 353

如果警报的顺序很重要,请使用:

for (var i = 0; i < str.length; i++) {
  alert(str.charAt(i));
}
Run Code Online (Sandbox Code Playgroud)

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

var i = str.length;
while (i--) {
  alert(str.charAt(i));
}
Run Code Online (Sandbox Code Playgroud)

  • 如另一个答案中所述,您可以使用str.charAt(i)代替[].有关为何使用charAt vs []的更多信息,请参阅[string.charAt(x)或string\[x \]](http://stackoverflow.com/questions/5943726/string-charatx-or-stringx) (12认同)
  • 我发现很难相信任何现代JS编译器会重新计算长度,如果字符串没有在循环内修改.在其他语言中,我很乐意在for循环的test子句中进行长度检查,假设编译器最了解并相应地对其进行优化. (12认同)
  • 注意:这不适用于包含UTF-8字符的字符串,例如 (4认同)
  • @Dagmar:Javascript 不使用 UTF-8,它使用 UTF-16(或 UCS-2,取决于浏览器)。每个单个字符都可以表示为 UTF-8 或 UTF-16,但没有这个问题。唯一有问题的是需要 UTF-16 中的四个字节而不是两个字节的那些。是一个需要四个字节的 UTF-16 字符。查找更多信息的关键术语是“星体平面”、“非 BMP”和“代理对”。 (3认同)
  • IE &lt;9不支持使用[[]`将字符放置在特定位置 (2认同)

Mr.*_*ito 173

它可能不仅仅是解决了.只想为另一个简单的解决方案做出贡献:

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);
});
Run Code Online (Sandbox Code Playgroud)

  • 没有意识到传播运算符在字符串上工作......整洁! (14认同)
  • 不,不能。`forEach()`将索引和数组作为第二和第三个参数传递。我宁愿不登录。 (6认同)
  • 其中,只有前两个会迭代字符串的字符。其余的则迭代 UTF-16 代码单元。例如,尝试 `text = "\ud835\udcaf\ud835\udcae\ud835\udca9"` 该字符串中有 3 个 unicode 字符,但有 6 个代码单元。 (4认同)
  • 最后一个例子可以简单地是`[... text] .forEach(console.log)` (3认同)
  • 请注意,扩展运算符(第一个示例)和 split 调用(最后一个示例)都将创建一个新数组。这通常不会成为问题,但对于大字符串或频繁使用来说可能会代价高昂。 (3认同)
  • 那么 `for (let c of [...text]) { console.log(c) }` 怎么样? (2认同)

mik*_*iku 73

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

for (var x = 0; x < str.length; x++)
{
    var c = str.charAt(x);
    alert(c);
}
Run Code Online (Sandbox Code Playgroud)

  • @EliGrey将长度放在变量中真的很重要吗?你有没有基准,当这比较少的代码行更可取? (8认同)
  • 此外,str.length应存储在变量中,因此不必继续访问. (2认同)

zur*_*fyx 60

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

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

对于

经典和迄今为止最具性能的.如果您计划在性能关键算法中使用它,或者它需要与浏览器版本的最大兼容性,那么您应该使用这个.

for (var i = 0; i < str.length; i++) {
  console.info(str[i]);
}
Run Code Online (Sandbox Code Playgroud)

为...的

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

let result = '';
for (let letter of str) {
  result += letter;
}
Run Code Online (Sandbox Code Playgroud)

的forEach

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

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

// ES6 version.
let result = '';
str.split('').forEach(letter => {
  result += letter;
});
Run Code Online (Sandbox Code Playgroud)

要么

var result = '';
str.split('').forEach(function(letter) {
  result += letter;
});
Run Code Online (Sandbox Code Playgroud)

以下是我不喜欢的.

对于在...

与......相比,你得到的是字母索引而不是字母.它的表现非常糟糕.

var result = '';
for (var letterIndex in str) {
  result += str[letterIndex];
}
Run Code Online (Sandbox Code Playgroud)

地图

功能方法,这是好的.但是,地图并不意味着用于此.当需要更改数组内的值时应该使用它,但事实并非如此.

// ES6 version.
var result = '';
str.split('').map(letter => {
  result += letter;
});
Run Code Online (Sandbox Code Playgroud)

要么

let result = '';
str.split('').map(function(letter) {
  result += letter;
});
Run Code Online (Sandbox Code Playgroud)

  • 基准在哪里?最快的解决方案是什么? (6认同)

hip*_*ail 37

大多数(如果不是全部)答案都是错误的,因为只要Unicode BMP(Basic Multilingual Plane)之外的字符串中有字符,它们就会中断.这意味着所有表情符号都将被打破.

JavaScript 对所有字符串使用UTF- 16 Unicode.在UTF-16中,BMP之外的字符由两部分组成,称为" 代理 ",这里的大多数答案将单独处理这些对的每个部分而不是单个字符.

至少从2016年开始,现代JavaScript的一种方法是使用新的String迭代器.以下是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"
Run Code Online (Sandbox Code Playgroud)

  • 有关将字符串拆分为字符同时考虑代理项对的现代解决方案,请参阅:/sf/answers/2981782821/ (3认同)

Adr*_*der 20

你可以试试这个

var arrValues = 'This is my string'.split('');
// Loop over each value in the array.
$.each(arrValues, function (intIndex, objValue) {
    alert(objValue);
})
Run Code Online (Sandbox Code Playgroud)

  • 仍然是一种选择,但不是高效的.不要把jQuery放在任何地方. (10认同)

loc*_*dev 10

简短的回答:Array.from(string)会给你你可能想要的东西,然后你可以迭代它或其他任何东西,因为它只是一个数组。

好吧,让我们试试这个字符串:abc|??\n??|???

代码点是:

97
98
99
124
9899, 65039
10
9898, 65039
124
128104, 8205, 128105, 8205, 128103, 8205, 128103
Run Code Online (Sandbox Code Playgroud)

所以有些字符有一个代码点(字节),有些字符有两个或更多,并添加了一个换行符以进行额外测试。

所以经过测试有两种方法:

  • 每字节字节(每个代码点的代码点)
  • 字符组(但不是整个家庭表情符号)

97
98
99
124
9899, 65039
10
9898, 65039
124
128104, 8205, 128105, 8205, 128103, 8205, 128103
Run Code Online (Sandbox Code Playgroud)


Pam*_*six 9

另一个解决方案......

var strg= 'This is my string';
for(indx in strg){
  alert(strg[indx]);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你只想要char而不是索引,那么使用`for..of` loop`(let ch of t){alert(ch)}会更快 (2认同)

Dow*_*oat 9

当我需要编写短代码或单行代码时,我使用这个"hack":

'Hello World'.replace(/./g, function (char) {
    alert(char);
    return char; // this is optional 
});
Run Code Online (Sandbox Code Playgroud)

这不会计算换行符,因此可能是好事还是坏事.如果要包含换行符,请替换:/./with /[\S\s]/.您可能会看到的其他单行可能会使用.split()哪个有很多问题

  • 我认为这不会考虑 Unicode 问题,除非它有 `u` 标志和 `g` 标志?好的,刚刚测试过,我是对的。 (2认同)

Mar*_*tke 8

如果字符串包含unicode字符,最好使用for ... of语句,因为字节大小不同.

for(var c of "tree ?") { console.log(c); }
//"A".length === 3
Run Code Online (Sandbox Code Playgroud)


Rob*_*avo 8

您可以像在数组中一样简单地迭代它:

for(var i in txt){
    console.log(txt[i]);
}
Run Code Online (Sandbox Code Playgroud)

  • 现在甚至是 `for (var i of txt) { console.log(i) }` (4认同)

小智 7

新的JS允许这样做:

const str = 'This is my string';
Array.from(str).forEach(alert);
Run Code Online (Sandbox Code Playgroud)


Adi*_*M P 7

您现在可以通过 using 迭代包含在 String 中的单个 Unicode 代码点String.prototype[@@iterator],它返回一个众所周知的 Symbol 类型Symbol.iterator的值 - 类数组对象的默认迭代器(String在这种情况下)。

示例代码:

const str = 'The quick red  jumped over the lazy ! ????';

let iterator = str[Symbol.iterator]();
let theChar = iterator.next();

while(!theChar.done) {
  console.log(theChar.value);
  theChar = iterator.next();
}

// logs every unicode character as expected into the console.
Run Code Online (Sandbox Code Playgroud)

这适用于 Unicode 字符,例如 emoji 或非罗马字符,它们会绊倒遗留结构。

参考:MDN 链接到 String.prototype@@iterator

  • 请注意,您可以使用“for ... of”循环以及字符串来以更短的方式完成此操作 - 这是用于访问迭代器的语法糖。 (2认同)

Mai*_*ini 7

在 ES6 / ES2015 中,您可以使用 迭代字符串iterators,如您所见

符号迭代器 MDN

var str = 'Hello';
var it = str[Symbol.iterator]();

for (let v of it) {
  console.log(v)
 }
 
//  "H"
//  "e"
//  "l"
//  "l"
//  "o"
Run Code Online (Sandbox Code Playgroud)

这是一种声明式风格优点是什么?您不必关心如何访问字符串的每个元素。


小智 6

您现在可以使用关键字.

    var s = 'Alien';
    for (var c in s) alert(s[c]);
Run Code Online (Sandbox Code Playgroud)

  • @Downgoat为什么?这有什么不好的?我的意思是,如果我知道我的Javascript引擎支持'in',并且我的代码将无法进入另一个引擎...为什么不使用它? (3认同)

小智 6

// There are multiple ways but I find this easiest.

let str = 'This is my string';
for(let character of str) 
  console.log(character)
Run Code Online (Sandbox Code Playgroud)


Ric*_*ich 5

您可以像这样获得各个字符的数组

var test = "test string",
    characters = test.split('');
Run Code Online (Sandbox Code Playgroud)

然后使用常规Javascript循环,否则你可以使用jQuery迭代字符串的字符

var test = "test string";

$(test.split('')).each(function (index,character) {
    alert(character);
});
Run Code Online (Sandbox Code Playgroud)


Vaj*_*ecz 5

如果您想在字符级别对文本进行转换,并在最后取回转换后的文本,您可以执行以下操作:

var value = "alma";
var new_value = [...value].map((x) => x+"E").join("")
Run Code Online (Sandbox Code Playgroud)

所以步骤:

  • 将字符串拆分为字符数组(列表)
  • 通过函子映射每个字符
  • 将生成的字符数组连接到生成的字符串中