Javascript를 사용하여 각 문자를 처리하려면 어떻게해야합니까?


361

문자열의 각 개별 문자에 알리고 싶지만 어떻게해야하는지 잘 모르겠습니다.

따라서 내가 가지고 있다면 :

var str = 'This is my string';

나는 T, h, i, s 등을 별도로 경고 할 수 있기를 원합니다. 이것은 제가 작업하고있는 아이디어의 시작일 뿐이지 만 각 문자를 개별적으로 처리하는 방법을 알아야합니다.

jQuery를 사용하고 문자열 길이를 테스트 한 후 split 함수를 사용해야 할 수도 있다고 생각했습니다.

아이디어?


3
아마 당신이 이것을 찾고 있었을 것 for(const c of str) { ... }입니다 : ES6 현재 . 그에 대한 자세한 내용은 아래에 자세히 설명되어 있지만 충분히 반박되지 않은 답변입니다. 추신 : @ARJUN의 링크가 작동하지 않습니다.
Max

답변:


419

경고 순서가 중요한 경우 다음을 사용하십시오.

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

경고 순서가 중요하지 않은 경우 다음을 사용하십시오.

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


2
사용하여 []특정 위치에 문자를 얻을 수는 IE <9에서 지원되지 않습니다
수직 동기화

13
다른 답변에서 다룬 것처럼 [] 대신에 str.charAt (i)를 사용할 수 있습니다. charAt vs []를 사용해야하는 이유에 대한 자세한 내용은 string.charAt (x) 또는 string [x]를
Julian Soro

12
루프에서 문자열을 수정하지 않은 경우 최신 JS 컴파일러가 길이를 다시 계산한다고 생각하기가 어렵습니다. 다른 모든 언어에서는 컴파일러가 가장 잘 알고 있고 그에 따라 최적화한다고 가정하면 행복하게 for 루프의 테스트 절에서 길이 검사를 수행합니다.
Echelon

3
@Dagmar : Javascript는 UTF-8을 사용하지 않고 UTF-16 (또는 브라우저에 따라 UCS-2)을 사용합니다. 모든 단일 문자는 UTF-8 또는 UTF-16으로 표시 될 수 있지만이 문제는 없습니다. 문제가있는 유일한 것은 2 바이트가 아닌 UTF-16의 4 바이트가 필요한 것입니다. 💩는 UTF-16에서 4 바이트가 필요한 문자입니다. 더 많은 정보를 찾는 핵심 용어는 "astral plane", "BMP 이외"및 "surrogate pair"입니다.
hippietrail

1
@Dagmar : Java와 Javascript는 모두 UTF-16 (이전 UCS-)을 공통으로 갖습니다. 그것을 사용하는 세 번째 주요 플랫폼은 Windows입니다. 유닉스, MacOS 및 인터넷 프로토콜은 UTF-8을 사용합니다. charAt대리 쌍이 없었고 문제를 해결하기 위해 UCS-2 일에서 남겨진 새로운 기능 codepointAt이 JavaScript에 추가되어 친숙한 똥 더미를 올바르게 처리합니다. Java도 가지고 있다고 생각합니다.
hippietrail

240

아마도 해결 된 것 이상입니다. 다른 간단한 솔루션으로 기여하고 싶습니다.

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);
});

4
마지막 예는 다음과 같습니다[...text].forEach(console.log)
Govind Rai

10
아니, 안돼 forEach()인덱스와 배열을 두 번째 및 세 번째 인수로 전달합니다. 차라리 기록하지 않겠습니다.
Mr. Goferito

1
스프레드 연산자 (첫 번째 예)와 스플릿 호출 (마지막 예) 모두 새 배열을 만듭니다. 이것은 일반적으로 문제가되지 않지만 큰 문자열이나 빈번한 사용에는 비용이 많이들 수 있습니다.
Randolpho

어때for (let c of [...text]) { console.log(c) }
Flimm

이를 통해 문자열에서 새 배열을 만듭니다. 이점이 보이지 않습니다. let c of text이미 작업을 수행합니다.
Mr. Goferito

73

순수한 자바 스크립트에서 가능한 해결책은 다음과 같습니다.

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

var x = 0 및 var c = str.charAt (x)를 사용하는 것이 좋습니다.
Rich

2
또한 str.length는 변수에 저장해야하므로 계속 액세스 할 필요가 없습니다.
Eli Gray

8
@EliGrey 변수에 길이를 넣는 것이 정말로 중요합니까? 더 적은 수의 코드 줄을 사용하는 것보다 이것이 바람직한 벤치 마크가 있습니까?
pm_labs 2

@paul_sns 흥미롭게도, Edge (10000 요소 배열의 경우 0.7ms 차이)에 약간의 차이 가있는 것 같습니다 : jsfiddle.net/carcigenicate/v8vvjoc1/1 . 완벽한 테스트는 아니지만 평균 10000 개의 테스트를 기반으로합니다.
발암 성 물질

1
@paul_sns 또한 흥미롭게도 Chrome은 약 2 %의 시간 (~ 5ms 대 ~ 0.0997ms)에서 동일한 테스트를 수행했으며 두 버전 모두 동일한 시간을 제공하므로 Edge가 최적화되지 않은 것처럼 보입니다.
Carcigenicate

69

각 텍스트를 처리하는 방법 (벤치 마크 포함)

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

...에 대한

권위 있는 과 지금까지 가장 성능이 뛰어난 제품 . 성능 결정 알고리즘에서 사용할 계획이거나 브라우저 버전과의 최대 호환성이 필요한 경우이 기능을 사용해야합니다.

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

...의

...의 새로운 ES6입니다 반복자를위한 입니다. 대부분의 최신 브라우저에서 지원합니다. 시각적으로 더 매력적이며 실수를 입력하는 경향이 적습니다. 프로덕션 응용 프로그램 에서이 작업을 수행하려는 경우 Babel 과 같은 변환기를 사용해야합니다 .

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

각각

기능적 접근. 에어 비앤비 승인 . 이 방법으로 수행 할 때의 가장 큰 단점 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];
}

지도

좋은 기능 접근. 그러나 map은 그 용도로 사용되지 않습니다. 배열 내부의 값을 변경해야 할 때 사용해야하지만, 그렇지 않습니다.

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

또는

let result = '';
str.split('').map(function(letter) {
  result += letter;
});

1
내 컴퓨터에서 클래식 for루프는 실제로 두 번째로 느 렸지만 가장 for...of빠릅니다 (약 3 배 빠름 for).
John Montgomery

1
벤치 마크는 어디에 있습니까? 가장 빠른 해결책은 무엇입니까?
poitroae '12

1
@johnywhy 2 년 전이었고 연결이 끊어 졌기 때문에 그때 얻은 결과를 어떻게 방어 할 것인지 잘 모르겠습니다. 새로운 벤치 마크를 설정하면 for루프가 약간 빨라지 면서 zurfyx의 결론에 동의 하게됩니다.
John Montgomery

1
@ JohnMontgomery 나는 당신이 아무것도 할 것으로 기대하지 않습니다. 미래 독자들에게 당신의 결과가 답과 다르다는 점에 유의하십시오. 2020 년 오늘 브라우저에 어떤 결과가 적용되는지 알고 싶습니다. 어느 링크가 죽었습니까?
johny 왜

1
@ johnywhy 모든 실제 테스트와 함께 맨 위에있는 링크는 404를 반환합니다.
John Montgomery

42

유니 코드 BMP (Basic Multilingual Plane) 외부의 문자열에 문자가있을 때마다 문자가 깨질 수 있기 때문에 대부분의 대답이 여기에 해당되지는 않습니다 . 즉, 모든 이모지가 깨질 것입니다 됩니다.

JavaScript는 모든 문자열에 UTF- 16 유니 코드를 사용합니다. 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"


4
서로 게이트 쌍을 고려하면서 문자열을 문자로 분리하는 현대적인 솔루션은 다음을 참조하십시오. stackoverflow.com/a/42596897/527702
hippietrail

20

당신은 이것을 시도 할 수 있습니다

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

11
여전히 옵션이지만 성능은 아닙니다. jQuery를 어디에나 두지 마십시오.
cagatay

10

하나 더 해결책 ...

var strg= 'This is my string';
for(indx in strg){
  alert(strg[indx]);
}

3
인덱스 만 사용하지 않고 문자 만 원하는 경우 for..of루프 를 사용하는 것이 더 빠릅니다.for (let ch of t) { alert(ch) }
Shaheen Ghiassy

10

짧은 코드 나 하나의 라이너를 작성해야 할 때이 "해킹"을 사용합니다.

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

이것은 개행을 계산하지 않으므로 좋은 일이거나 나쁜 일이 될 수 있습니다. 당신은 어떤 줄 바꿈을 포함 할 경우, 교체 : /.//[\S\s]/. 다른 하나 - 라이너 당신은 아마 사용 볼 수 .split()있는 많은 문제를 가지고


가장 좋은 답변입니다. 유니 코드의 문제점을 고려하고 .map () 등의 기능적 구성물과 함께 사용할 수도 있습니다.
rofrol

나는에 액세스 할 때 나는이 일에 대해 좋아하지 않는 한가지는 에 전달 추가 PARAMS forEach전화의 기능 은 VS PARAMS가 전송을replace . ASCIIing을 알고 있다면에 대한 사용 사례가 여전히 있다고 생각합니다 split. 그래도 좋은 대답입니다!
ruffin

이 답변에는 어쨌든 확인할 값을 미리 선택하는 보너스가 있습니다.
Fuzzyma

1
u플래그와 함께 플래그 가 없으면 유니 코드 문제를 고려하지 않을 것이라고 생각 g했습니까? 방금 테스트를 마쳤습니다.
hippietrail

9

새로운 JS는 이것을 허용합니다 :

const str = 'This is my string';
Array.from(str).forEach(alert);

8

바이트 크기가 다르기 때문에 문자열에 유니 코드 문자가 포함되어 있으면 for ... of 문을 사용하는 것이 좋습니다.

for(var c of "tree 木") { console.log(c); }
//"𝐀A".length === 3

7

짧은 대답 : Array.from(string)아마도 당신이 원하는 것을 줄 것이고 배열이기 때문에 또는 그것을 반복 할 수 있습니다.

다음 문자열로 시도해 봅시다 : abc|⚫️\n⚪️|👨‍👩‍👧‍👧.

코드 포인트는 다음과 같습니다.

97
98
99
124
9899, 65039
10
9898, 65039
124
128104, 8205, 128105, 8205, 128103, 8205, 128103

따라서 일부 문자에는 하나의 코드 포인트 (바이트)가 있고 일부 문자에는 둘 이상의 코드가 있으며 추가 테스트를 위해 줄 바꿈이 추가되었습니다.

테스트 후 두 가지 방법이 있습니다.

  • 바이트 당 바이트 (코드 포인트 당 코드 포인트)
  • 캐릭터 그룹 (가족 이모티콘은 아님)

string = "abc|⚫️\n⚪️|👨‍👩‍👧‍👧"

console.log({ 'string': string }) // abc|⚫️\n⚪️|👨‍👩‍👧‍👧
console.log({ 'string.length': string.length }) // 21

for (let i = 0; i < string.length; i += 1) {
  console.log({ 'string[i]': string[i] }) // byte per byte
  console.log({ 'string.charAt(i)': string.charAt(i) }) // byte per byte
}

for (let char of string) {
  console.log({ 'for char of string': char }) // character groups
}

for (let char in string) {
  console.log({ 'for char in string': char }) // index of byte per byte
}

string.replace(/./g, (char) => {
  console.log({ 'string.replace(/./g, ...)': char }) // byte per byte
});

string.replace(/[\S\s]/g, (char) => {
  console.log({ 'string.replace(/[\S\s]/g, ...)': char }) // byte per byte
});

[...string].forEach((char) => {
  console.log({ "[...string].forEach": char }) // character groups
})

string.split('').forEach((char) => {
  console.log({ "string.split('').forEach": char }) // byte per byte
})

Array.from(string).forEach((char) => {
  console.log({ "Array.from(string).forEach": char }) // character groups
})

Array.prototype.map.call(string, (char) => {
  console.log({ "Array.prototype.map.call(string, ...)": char }) // byte per byte
})

var regexp = /(?:[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g

string.replace(regexp, (char) => {
  console.log({ 'str.replace(regexp, ...)': char }) // character groups
});


7

이제 배열을 사용하는 객체 ( 이 경우) 의 기본 반복자 String.prototype[@@iterator]인 잘 알려진 Symbol 유형의 값을 반환하는 을 사용하여 문자열에 포함 된 개별 유니 코드 코드 포인트를 반복 할 수 있습니다 .Symbol.iteratorString

예제 코드 :

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.

레거시 구문을 트립하는 이모티콘 또는 비 로마자와 같은 유니 코드 문자와 함께 작동합니다.

참조 : String.prototype @@ iterator에 대한 MDN 링크 .


2
for ... of문자열을 반복 하는 루프를 사용하여 더 짧은 방식으로이 작업을 수행 할 수 있습니다 . 즉, 반복자에 액세스하기위한 구문 설탕입니다.
Aditya MP

6

이제 키워드 에서 사용할 수 있습니다 .

    var s = 'Alien';
    for (var c in s) alert(s[c]);


필터를 사용하지
않으면

4
@ Downgoat 왜? 뭐가 나쁜거야? 내 자바 스크립트 엔진에서 'in'을 지원하고 코드가 다른 엔진으로 들어 가지 않는다는 것을 알고있는 상황에 처한 경우 ... 사용하지 않는 이유는 무엇입니까?
TKoL

참조 @TKoL .
Alan

@Alan in은 언어의 합법적 인 부분입니다. 적절한 것을 사용하십시오. 기사에서는 in숫자 키와 동일한 알파 키 를 해석하도록 주의 합니다. 그래서? 어쩌면 그것은 당신이 원하는 것입니다. 다른 방법은 알파 키를 잘못 무시 한다고 말할 수도 있습니다 . 이모, of올바른 행동을했습니다. JS 배열에서 알파 키가없는 요소에는 여전히 키가 있습니다 (숫자). 내 콘솔에서 JS는 "정확하게"알파 키를 숫자 키와 동일하게 취급합니다.>const arr = ['a', 'b'] >arr.test = 'hello' >arr 0: "a" 1: "b" test: "hello" length: 2
johny 왜

5

개별 문자 배열을 얻을 수 있습니다.

var test = "test string",
    characters = test.split('');

그런 다음 일반 자바 스크립트를 사용하여 반복하거나 그렇지 않으면 jQuery by를 사용하여 문자열의 문자를 반복 할 수 있습니다

var test = "test string";

$(test.split('')).each(function (index,character) {
    alert(character);
});

5

를 사용하여이 문자열을 문자 배열로 변환 split()한 다음 반복 할 수 있습니다.

const str = "javascript";
const strArray = str.split('');

strArray.map(s => console.log(s));


분명히 이것은 유니 코드 문자와 그래픽 기호로 실패합니다.
johny 왜

4

문자 수준에서 텍스트를 변환하고 마지막에 변환 된 텍스트를 다시 가져 오려면 다음과 같이하십시오.

var value = "alma";
var new_value = value.split("").map(function(x) { return x+"E" }).join("")

단계는 다음과 같습니다.

  • 문자열을 문자 배열 (목록)로 분할
  • 펑터를 통해 각 캐릭터를 매핑
  • 결과 문자 배열을 결과 문자열에 결합

0

오늘의 JavaScript에서는

Array.prototype.map.call('This is my string', (c) => c+c)

분명히 c + c는 c로하고 싶은 모든 것을 나타냅니다.

이 반환

["TT", "hh", "ii", "ss", " ", "ii", "ss", " ", "mm", "yy", " ", "ss", "tt", "rr", "ii", "nn", "gg"]


아마도 :[...'This is my string'].map((c)=>c+c)
앨런

0

이것은 오래된 브라우저에서 작동하며 💩와 같은 UTF-16 문자로 작동합니다.

이것이 가장 호환 가능한 솔루션이어야합니다. 그러나 for루프 보다 성능이 떨어집니다 .

내가 사용하는 정규 표현식 생성 regexpu을

var str = 'My String 💩 ';
var regEx = /(?:[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g


str.replace(regEx, function (char) {
    console.log(char)
});

도움이 되었기를 바랍니다!


"낮은 perfomant"는 무엇을 의미합니까? 요구 사항에 더 적합하고 성능이 우수하므로 "느린"것을 의미한다고 생각합니다.
hippietrail

-1

당신은 할 수 있습니다 단일 문자 액세스str.charAt(index)str[index]. 그러나 후자의 방법은 ECMAScript의 일부가 아니므로 전자의 방법을 사용하는 것이 좋습니다.


나는 멀리 떨어져있을 것입니다. 불행히도 모든 버전의 IE에서는 작동하지 않습니다. 날 믿어. 나는 그것을 어려운 길을 배웠다.
Xavi

3
ECMAScript의 일부이지만 3 차가 아닌 새로 출시 된 5 차 버전에서만 제공됩니다.
kangax

-1

각 캐릭터에 애니메이션을 적용하려면 span 요소로 감싸 야합니다.

var $demoText = $("#demo-text");
$demoText.html( $demoText.html().replace(/./g, "<span>$&amp;</span>").replace(/\s/g, " "));

나는 이것이 최선의 방법이라고 생각하고 범위를 처리합니다. (예 : TweenMax 사용)

TweenMax.staggerFromTo ($ demoText.find ( "span"), 0.2, {autoAlpha : 0}, {autoAlpha : 1}, 0.1);


-1

이 코드를 사용해보십시오

    function myFunction() {
    var text =(document.getElementById("htext").value); 
    var meow = " <p> <,> </p>";
    var i;


    for (i = 0; i < 9000; i++) {

        text+=text[i] ;



    }

    document.getElementById("demo2").innerHTML = text;

}
</script>
<p>Enter your text: <input type="text" id="htext"/>

    <button onclick="myFunction();">click on me</button>
</p>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.