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 docsを参照してください。


31
これは、サロゲートペアを考慮していません。"𨭎".split('')結果は["�", "�"]です。
ヒッピートレイル2015

59
このスレッドの他の場所で@hakatashiの回答を参照してください。うまくいけば誰もがこれを目にします... この方法を使用しないでください、
それはユニコードセーフではあり

3
パーティーに少し遅れました。しかし、なぜ誰かが文字列の配列を作りたいのでしょうか?文字列はすでに配列ですか、それとも間違っていますか? "randomstring".length; //12 "randomstring"[2]; //"n"
Luigi van der Pal 2016

4
@LuigivanderPal文字列は配列ではありませんが、非常に似ています。ただし、文字の配列とは異なります。文字列は16ビットの数値の配列に似ており、その一部は文字を表し、一部はサロゲートペアの半分を表します。たとえばstr.length、一部の文字は他の文字より多くのスペースを取るため、文字列の文字数はわかりません。str.length16ビットの数値の数を示します。
Theodore Norvell

289

ヒッピー・トレイルを示唆MEDERの答えは、サロゲートペアと誤解に破ることができる「の文字が。」例えば:

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

これらの文字シーケンスを正しく処理するには、次のES2015機能のいずれかを使用することをお勧めします。

スプレッド構文(すでに insertusernamehereで回答済み)

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

Array.from

> 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文字は、「大きな」コードポイントを持つ(Unicodeテーブル内の)追加の文字プレーンからのものであるため、16バイトに収まりません。JavaScriptで使用されるutf-16エンコーディングは、これらの文字をサロゲートペア(追加のプレーンから他の文字を形成するためにペアとしてのみ使用される特殊文字)として提示します。メインキャラクタープレーンの文字のみが16バイトで表示されます。それが意味をなすならば、シュルガーテペアの特殊文字もメインキャラクタープレーンからのものです。
Olga

1
さまざまなテクニックのパフォーマンス、スプレッドopはチャンプ(クロム58)のように見えます。
エイドリアン2017年

4
このソリューションは🏳️‍🌈、などの一部の絵文字を分割し、発音区別記号を組み合わせて文字から分割することに注意してください。文字ではなく書記素クラスタに分割する場合は、stackoverflow.com / a / 45238376を参照してください。
user202729 2018

3
サロゲートペアを分解しないことはすばらしいことですが、「文字」(より正確には、書記素)をまとめるための汎用的な解決策ではないことに注意してください。書記素は複数のコードポイントで構成できます。たとえば、デバナーガリ語の名前は "देवनागरी"で、ネイティブスピーカーによって5つの書記素として読み取られますが、8つのコードポイントを使用して生成されます...
TJ Crowder

71

spread構文

ECMAScript 2015(ES6)標準で導入された配列初期化子であるスプレッド構文を使用できます。

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

最初の3つの結果は次のようになります。

["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"(PHPRubyなど)または " scatter"(Pythonなど)としても参照されます。


デモ

購入前にお試しください


1
ES5へのコンパイラと組み合わせて拡散演算子を使用する場合、これはIEでは機能しません。それを考慮してください。問題が何であるかを理解するのに何時間もかかりました。
Stef van den Berg


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クラウダー2018

@TJCrowderこれは長い道のりです[..."Hello, world"]
chharvey

@chharvey-へえ。:-)
TJ

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 2010

3
確実にクロスブラウザできないわけではありません。これはECMAScript Fifth Editionの機能です。
ボビンス

8
クロスブラウザのバージョンはmystring.charAt(index)です。
psmay 2010

1
+1 charAt()for-ただし、配列のようなバリアントを使用したいのですが。くそーIE
Zenexer 2014

4

「キャラクター」として考えることができる(少なくとも)3つの異なるものがあります。その結果、使用したいアプローチの3つの異なるカテゴリがあります。

UTF-16コード単位への分割

JavaScript文字列はもともと、UTF-16コードユニットとUnicodeコードポイントの間に1対1の関係があった歴史のある時点で、UTF-16コードユニットのシーケンスとして発明されました。.length文字列のプロパティは、その長さをUTF-16コード単位で測定します。これを行うsomeString[i]と、i番目のUTF-16コード単位を取得しますsomeString

したがって、インデックス変数を含むCスタイルのforループを使用して、文字列から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つのUnicodeコードポイント(コードポイント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);

Unicodeコードポイントへの分割

そのため、おそらく、代わりに文字列をUnicodeコードポイントに分割する必要があります。ECMAScript 2015がイテラブルの概念を言語に追加して以来、それは可能でした。文字列は反復可能になり、(for...ofループなどで)文字列を反復すると、UTF-16コード単位ではなく、Unicodeコードポイントが取得されます。

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

Array.from暗黙的に渡された反復可能オブジェクトを反復処理するを使用して、これを短縮できます。

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

しかし、Unicodeのコードポイントは、おそらく「文字」と考えることができる可能な限り最大のものではありませんどちらか。合理的に単一の「文字」と見なすことができるが、複数のコードポイントで構成されているものの例には、次のものがあります。

  • アクセント記号付き文字(アクセントが結合コードポイントと共に適用される場合)
  • いくつかの絵文字

上記の反復メカニズムを使用して、このような文字を含む文字列を配列に変換しようとすると、結果の配列で文字が分割されてしまうことがわかります。(システムに表示されない文字がある場合、yourString以下は、アクセント記号付きの大文字のAと、それに続くイギリスの旗、黒人女性で構成されます。)

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

これらのそれぞれを最終的な配列の1つの項目として保持する場合は、書記素の配列が必要です。、コードポイントではなくです。

書記素に分割する

JavaScriptにはこれに対する組み込みサポートがありません-少なくともまだです。したがって、コードポイントのどの組み合わせが書記素を構成するかについてのUnicodeルールを理解して実装するライブラリが必要です。幸い、orlingのgrapheme-splitterが存在します。npmでインストールするか、npmを使用していない場合は、index.jsファイルをダウンロードして、<script>タグを付けて提供します。このデモでは、jsDelivrからロードします。

書記素スプリッタは私たちに与えますGraphemeSplitter:三つの方法でクラスをsplitGraphemesiterateGraphemescountGraphemes。当然のことながら、我々はしたいです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>

そして、私たちはそこにいます- おそらくあなたが望んだものである3つの書記素の配列です。


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
このアプローチは宣言型よりもやや必須ですが、このスレッドでは最もパフォーマンスが高く、より多くの愛に値します。一つの限界位置することにより、文字列の文字を取得するには、過去の文字を扱うときである基本多言語計画など絵文字などのUnicodeインチ "😃".charAt(0)使用できない文字が返されます
KyleMit

2
@KyleMitこれは短い入力にのみ当てはまるようです。より長い入力を使用すると、.split("")再び最速のオプションになります
Lux

1
また.split("")、Firefoxでは大幅に最適化されているようです。ループはクロームで同様のパフォーマンスを持ち、Firefoxの分割は、Firefoxで入力が小さい場合と大きい場合で大幅に高速になります。
ラックス


0

1つの可能性は次のとおりです。

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(''));


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.