JavaScript에서 문자열을 문자 배열로 가져 오는 방법은 무엇입니까?


369

JavaScript에서 문자열을 문자형 배열로 어떻게 변환합니까?

"Hello world!"배열 과 같은 문자열을 얻는 것을 생각하고 있습니다.
['H','e','l','l','o',' ','w','o','r','l','d','!']

답변:


492

참고 : 이것은 유니 코드와 호환되지 않습니다. "I💖U".split('')4 개의 문자 배열이 ["I", "�", "�", "u"]발생하여 위험한 버그가 발생할 수 있습니다. 안전한 대안은 아래 답변을 참조하십시오.

빈 문자열로 나누십시오.

var output = "Hello world!".split('');
console.log(output);

String.prototype.split()MDN 문서를 참조하십시오 .


31
이것은 대리 쌍을 고려하지 않습니다. "𨭎".split('')결과 ["�", "�"].
hippietrail

59
이 스레드의 다른 곳에서 @hakatashi의 답변을 참조하십시오. 잘만되면 모든 사람이 이것을 본다 ... 이 방법을 사용하지 마십시오, 그것은 안전하지 않습니다
i336_

3
파티에 늦었 어 그러나 왜 누군가가 문자열 배열을 만들고 싶습니까? 문자열이 이미 배열이거나 틀렸습니까? "randomstring".length; //12 "randomstring"[2]; //"n"
Luigi van der Pal

4
@LuigivanderPal 문자열은 배열이 아니지만 매우 유사합니다. 그러나 문자 배열과 유사하지 않습니다. 문자열은 16 비트 숫자의 배열과 유사하며 일부는 문자를 나타내고 일부는 서로 게이트 쌍의 절반을 나타냅니다. 예를 들어, str.length일부 문자는 다른 문자보다 많은 공간을 차지하므로 문자열의 문자 수를 알려주지 않습니다. str.length16 비트 숫자의 수를 알려줍니다.
Theodore Norvell

289

으로 hippietrail 알 , MEDER의 대답은 서로 게이트 쌍과 오해 깰 수 "자." 예를 들면 다음과 같습니다.

// DO NOT USE THIS!
> '𝟘𝟙𝟚𝟛'.split('')
[ '�', '�', '�', '�', '�', '�', '�', '�' ]

이러한 문자 시퀀스를 올바르게 처리하려면 다음 ES2015 기능 중 하나를 사용하는 것이 좋습니다.

(확산 구문 이미 대답 insertusernamehere에 의해)

> [...'𝟘𝟙𝟚𝟛']
[ '𝟘', '𝟙', '𝟚', '𝟛' ]

배열

> Array.from('𝟘𝟙𝟚𝟛')
[ '𝟘', '𝟙', '𝟚', '𝟛' ]

RegExp u플래그

> '𝟘𝟙𝟚𝟛'.split(/(?=[\s\S])/u)
[ '𝟘', '𝟙', '𝟚', '𝟛' ]

사용 /(?=[\s\S])/u대신 /(?=.)/u하기 때문에 .줄 바꿈과 일치하지 않습니다 .

당신이 ES5.1 시대에 여전히 (또는 브라우저가 올바르게 정규식을 처리하지 않는 경우 - 에지 같은) 경우,이 대안을 사용할 수 있습니다 (에 의해 transpiled 바벨 ) :

> '𝟘𝟙𝟚𝟛'.split(/(?=(?:[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))/);
[ '𝟘', '𝟙', '𝟚', '𝟛' ]

Babel은 일치하지 않는 대리자를 올바르게 처리하려고 시도합니다. 그러나 이것은 대리가 낮은 대리모에 대해서는 효과가없는 것 같습니다.

브라우저에서 모두 테스트하십시오.


이 캐릭터들을 어떻게 구성 했습니까? 각 문자가 4 바이트 인 것 같습니다.
user420667

2
@ user420667 문자는 "큰"코드 포인트가있는 추가 문자 평면 (유니 코드 테이블)의 문자이므로 16 바이트에 맞지 않습니다. 자바 스크립트에서 사용되는 utf-16 인코딩은 이러한 문자를 서로 게이트 쌍 (추가 평면에서 다른 문자를 형성하기 위해 쌍으로 만 사용되는 특수 문자)으로 표시합니다. 주 캐릭터 평면에는 16 바이트 문자 만 표시됩니다. Surrugate 쌍 특수 문자도 기본 문자 평면에서 나온 것입니다.
Olga

1
다른 기술의 성능 , 확산 op 챔피언처럼 보인다 (크롬 58).
Adrien

4
이 솔루션은와 같은 일부 이모티콘을 분할하고 🏳️‍🌈분음 부호를 문자와 결합하여 분할합니다. 문자 대신 grapheme 클러스터로 분할하려면 stackoverflow.com/a/45238376을 참조하십시오 .
user202729

3
대리 쌍을 분리하지 않는 것이 좋지만 "문자"(또는보다 정확하게 graphemes )를 함께 유지하기위한 범용 솔루션은 아닙니다 . grapheme은 여러 코드 포인트로 구성 될 수 있습니다. 예를 들어, 언어 Devanagari의 이름은 "देवनागरी"인데,이 언어는 원어민이 5 개의 graphemes로 읽지 만 8 개의 코드 포인트를 생성하여 생성합니다 ...
TJ Crowder

71

spread구문

ECMAScript 2015 (ES6) 표준에 도입 된 Array Initializer 인 spread 구문을 사용할 수 있습니다 .

var arr = [...str];

function a() {
    return arguments;
}

var str = 'Hello World';

var arr1 = [...str],
    arr2 = [...'Hello World'],
    arr3 = new Array(...str),
    arr4 = a(...str);

console.log(arr1, arr2, arr3, arr4);

처음 세 결과는 다음과 같습니다.

["H", "e", "l", "l", "o", " ", "W", "o", "r", "l", "d"]

마지막 결과

{0: "H", 1: "e", 2: "l", 3: "l", 4: "o", 5: " ", 6: "W", 7: "o", 8: "r", 9: "l", 10: "d"}

브라우저 지원

ECMAScript ES6 호환성 표를 확인하십시오 .


추가 자료

spread" splat"(예 : PHP 또는 Ruby 또는 " scatter"(예 : Python )) 라고도 합니다.


데모

구입하기 전에 시도


1
ES5에 대한 컴파일러와 함께 스프레드 연산자를 사용하면 IE에서 작동하지 않습니다. 그것을 고려하십시오. 문제가 무엇인지 알아내는 데 몇 시간이 걸렸습니다.
Stef van den Berg

13

을 사용할 수도 있습니다 Array.from.

var m = "Hello world!";
console.log(Array.from(m))

이 방법은 ES6에서 도입되었습니다.

참고

배열


10

이것은 오래된 질문이지만 아직 나열되지 않은 다른 솔루션을 발견했습니다.

Object.assign 함수를 사용하여 원하는 출력을 얻을 수 있습니다.

var output = Object.assign([], "Hello, world!");
console.log(output);
    // [ 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!' ]

반드시 옳고 그른 것은 아니며 다른 옵션 일뿐입니다.

Object.assign은 MDN 사이트에 잘 설명되어 있습니다.


2
에 먼 길 Array.from("Hello, world")입니다.
TJ Crowder

@TJCrowder 그것은 먼 길입니다[..."Hello, world"]
chharvey

@chharvey-허. :-)
TJ Crowder

9

이미 다음과 같습니다.

var mystring = 'foobar';
console.log(mystring[0]); // Outputs 'f'
console.log(mystring[3]); // Outputs 'b'

또는 더 오래된 브라우저 친화적 인 버전의 경우 다음을 사용하십시오.

var mystring = 'foobar';
console.log(mystring.charAt(3)); // Outputs 'b'


4
-1 : 그렇지 않다. 그것을 시도 :alert("Hello world!" == ['H','e','l','l','o',' ','w','o','r','l','d'])
R. 마르틴 페르난데스에게

4
죄송합니다. 내가 말하고자하는 것은 "문자 배열을 만들지 않고 이와 같은 색인 참조로 개별 문자에 액세스 할 수 있다는 것"입니다.
dansimau

3
브라우저 간을 안정적으로 교차 할 수 없습니다. ECMAScript Fifth Edition 기능입니다.
bobince

8
크로스 브라우저 버전은 mystring.charAt(index)입니다.
psmay

1
charAt()--1은 +1 이지만, 배열 식 변형을 사용하는 것이 좋습니다. Darn IE.
Zenexer

4

"캐릭터"로 생각할 수있는 것은 적어도 세 가지가 있으며 결과적으로 세 가지 다른 범주의 접근 방식을 사용할 수 있습니다.

UTF-16 코드 단위로 분할

JavaScript 문자열은 원래 UTF-16 코드 단위와 유니 코드 코드 포인트간에 일대일 관계가 있었을 때 역사상 어느 시점에서 UTF-16 코드 단위의 시퀀스로 발명되었습니다. .length문자열 의 속성은 UTF-16 코드 단위의 길이를 측정하며, 그럴 때 i 번째 UTF-16 코드 단위 someString[i]를 얻습니다.someString .

결과적으로 인덱스 변수와 함께 C 스타일 for-loop를 사용하여 문자열에서 UTF-16 코드 단위 배열을 얻을 수 있습니다 ...

const yourString = 'Hello, World!';
const charArray = [];
for (let i=0; i<=yourString.length; i++) {
    charArray.push(yourString[i]);
}
console.log(charArray);

.split()빈 문자열을 구분 기호로 사용하는 것과 같이 동일한 일을 달성하는 여러 가지 짧은 방법도 있습니다 .

const charArray = 'Hello, World!'.split('');
console.log(charArray);

그러나 문자열에 여러 UTF-16 코드 단위로 구성된 코드 포인트가 포함되어 있으면이를 개별 코드 단위로 분할하므로 원하는 것이 아닐 수 있습니다. 예를 들어 문자열 '𝟘𝟙𝟚𝟛'은 4 개의 유니 코드 코드 포인트 (코드 포인트 0x1D7D8-0x1D7DB)로 구성되며, UTF-16에서는 각각 2 개의 UTF-16 코드 단위로 구성됩니다. 위의 방법을 사용하여 해당 문자열을 분할하면 8 개의 코드 단위 배열이 생성됩니다.

const yourString = '𝟘𝟙𝟚𝟛';
console.log('First code unit:', yourString[0]);
const charArray = yourString.split('');
console.log('charArray:', charArray);

유니 코드 코드 포인트로 분할

따라서 대신 문자열을 유니 코드 코드 포인트로 분할하려고합니다! ECMAScript 2015 가 언어에 iterable 이라는 개념을 추가 한 이후 가능했습니다 . 문자열은 이제 반복 가능하며 반복 할 때 (예 : for...of루프 사용) UTF-16 코드 단위가 아닌 유니 코드 코드 포인트를 얻습니다.

const yourString = '𝟘𝟙𝟚𝟛';
const charArray = [];
for (const char of yourString) {
  charArray.push(char);
}
console.log(charArray);

우리는 이것을 Array.from암시 적으로 전달 된 iterable에 대해 반복 하여 이것을 단축 할 수 있습니다 :

const yourString = '𝟘𝟙𝟚𝟛';
const charArray = Array.from(yourString);
console.log(charArray);

그러나 유니 코드 코드 포인트는 아마도 "문자"로 간주 될 수있는 가장 큰 가능한 것이 아니다 중 하나 . 합리적으로 단일 "문자"로 간주 될 수 있지만 여러 코드 포인트로 구성 될 수있는 몇 가지 예는 다음과 같습니다.

  • 악센트가 결합 코드 포인트로 적용된 경우 악센트 문자
  • 플래그
  • 일부 이모티콘

위의 반복 메커니즘을 통해 이러한 문자가 포함 된 문자열을 배열로 변환하려고하면 결과 배열에서 문자가 분리됩니다. (시스템에서 캐릭터가 렌더링되지 않는 경우 yourString아래는 급성 악센트 가있는 대문자 A , 영국 국기, 흑인 여성으로 구성됩니다.)

const yourString = 'Á🇬🇧👩🏿';
const charArray = Array.from(yourString);
console.log(charArray);

최종 배열에서 이들 각각을 단일 항목으로 유지하려면 코드 포인트가 아닌 graphemes 배열이 필요합니다 .

그래 핀으로 분할

JavaScript는 적어도 아직 지원하지 않습니다. 그래서 우리는 코드 포인트의 조합이 grapheme을 구성하는 유니 코드 규칙을 이해하고 구현하는 라이브러리가 필요합니다. 다행히도 orling의 grapheme-splitter가 있습니다. npm으로 설치하거나 npm을 사용하지 않는 경우 index.js 파일을 다운로드하여<script> 태그 . 이 데모에서는 jsDelivr에서로드하겠습니다.

그래 핀 스플리터는 우리에게 제공합니다 GraphemeSplitter: 세 가지 방법으로 클래스를 splitGraphemes, iterateGraphemes하고 countGraphemes. 당연히, 우리는 원한다 splitGraphemes:

const splitter = new GraphemeSplitter();
const yourString = 'Á🇬🇧👩🏿';
const charArray = splitter.splitGraphemes(yourString);
console.log(charArray);
<script src="https://cdn.jsdelivr.net/npm/grapheme-splitter@1.0.4/index.js"></script>

그리고 거기에 우리는 세 개의 graphemes의 배열입니다 . 아마 당신이 원했던 것일 것입니다.


2

문자열 길이를 반복 하고 각 위치에서 문자를 푸시 할 수 있습니다 .

const str = 'Hello World';

const stringToArray = (text) => {
  var chars = [];
  for (var i = 0; i < text.length; i++) {
    chars.push(text[i]);
  }
  return chars
}

console.log(stringToArray(str))


1
이 접근법은 선언적보다 조금 더 중요하지만, 이 스레드에서 가장 성능 이 뛰어나고 더 많은 사랑을받을 자격이 있습니다. 위치별로 문자열에서 문자검색하는 한 가지 제한 은 이모티콘과 같은 유니 코드에서 기본 다국어 계획 을 지나는 문자를 처리 할 때 입니다. 사용할 수없는 문자를 반환합니다"😃".charAt(0)
KyleMit

2
@KyleMit 이것은 짧은 입력에 대해서만 사실 인 것 같습니다. 더 긴 입력을 사용 .split("")하면 가장 빠른 옵션을 다시 사용할 수 있습니다
Lux

1
또한 .split("")무겁게 파이어 폭스에 최적화 된 것으로 보인다. 루프의 크롬 성능은 비슷하지만 파이어 폭스 분할은 파이어 폭스에서 크고 작은 입력에 대해 훨씬 빠릅니다.
Lux


0

하나의 가능성은 다음입니다.

console.log([1, 2, 3].map(e => Math.random().toString(36).slice(2)).join('').split('').map(e => Math.random() > 0.5 ? e.toUpperCase() : e).join(''));

-1

이건 어때요?

function stringToArray(string) {
  let length = string.length;
  let array = new Array(length);
  while (length--) {
    array[length] = string[length];
  }
  return array;
}

@ KyleMit 이것은 i 루프보다 빠릅니다. jsperf.com/string-to-character-array/3
msand

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.