Bagaimana Anda mendapatkan string ke array karakter dalam JavaScript?


369

Bagaimana Anda mengonversi string ke array karakter dalam JavaScript?

Saya sedang berpikir mendapatkan string suka "Hello world!"ke array
['H','e','l','l','o',' ','w','o','r','l','d','!']

Jawaban:


492

Catatan: Ini bukan unicode compliant. "I๐Ÿ’–U".split('')menghasilkan array 4 karakter ["I", "๏ฟฝ", "๏ฟฝ", "u"]yang dapat menyebabkan bug berbahaya. Lihat jawaban di bawah untuk alternatif yang aman.

Hanya membaginya dengan string kosong.

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

Lihat String.prototype.split()dokumen MDN .


31
Ini tidak memperhitungkan pasangan pengganti. "๐จญŽ".split('')hasil dalam ["๏ฟฝ", "๏ฟฝ"].
hippietrail

59
Lihat jawaban @ hakatashi di tempat lain di utas ini. Semoga semua orang melihat ini ... JANGAN GUNAKAN METODE INI, BUKAN UNICODE AMAN
i336_

3
Agak terlambat ke pesta. Tetapi mengapa seseorang ingin membuat larik string? Sebuah string sudah menjadi array atau saya salah? "randomstring".length; //12 "randomstring"[2]; //"n"
Luigi van der Pal

4
@LuigivanderPal Sebuah string bukan array, tetapi sangat mirip. Namun, ini tidak mirip dengan array karakter. String mirip dengan array angka 16-bit, beberapa di antaranya mewakili karakter dan beberapa di antaranya mewakili setengah dari pasangan pengganti. Misalnya, str.lengthtidak memberi tahu Anda jumlah karakter dalam string, karena beberapa karakter mengambil lebih banyak ruang daripada yang lain; str.lengthmemberi tahu Anda nomor angka 16-bit.
Theodore Norvell

290

Seperti yang dikatakan hippietrail , jawaban meder dapat mematahkan pasangan pengganti dan salah mengartikan "karakter". Sebagai contoh:

// DO NOT USE THIS!
> '๐Ÿ˜๐Ÿ™๐Ÿš๐Ÿ›'.split('')
[ '๏ฟฝ', '๏ฟฝ', '๏ฟฝ', '๏ฟฝ', '๏ฟฝ', '๏ฟฝ', '๏ฟฝ', '๏ฟฝ' ]

Saya sarankan menggunakan salah satu fitur ES2015 berikut untuk menangani urutan karakter ini dengan benar.

Sebarkan sintaks ( sudah dijawab oleh insertusernamehere)

> [...'๐Ÿ˜๐Ÿ™๐Ÿš๐Ÿ›']
[ '๐Ÿ˜', '๐Ÿ™', '๐Ÿš', '๐Ÿ›' ]

Dari Array

> Array.from('๐Ÿ˜๐Ÿ™๐Ÿš๐Ÿ›')
[ '๐Ÿ˜', '๐Ÿ™', '๐Ÿš', '๐Ÿ›' ]

uBendera RegExp

> '๐Ÿ˜๐Ÿ™๐Ÿš๐Ÿ›'.split(/(?=[\s\S])/u)
[ '๐Ÿ˜', '๐Ÿ™', '๐Ÿš', '๐Ÿ›' ]

Gunakan /(?=[\s\S])/usebagai ganti /(?=.)/ukarena .tidak cocok dengan baris baru .

Jika Anda masih di era ES5.1 (atau jika browser Anda tidak menangani regex ini dengan benar - seperti Edge), Anda dapat menggunakan alternatif ini (ditranslasikan oleh Babel ):

> '๐Ÿ˜๐Ÿ™๐Ÿš๐Ÿ›'.split(/(?=(?:[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))/);
[ '๐Ÿ˜', '๐Ÿ™', '๐Ÿš', '๐Ÿ›' ]

Perhatikan, bahwa Babel mencoba untuk menangani pengganti yang tidak cocok dengan benar. Namun, ini tampaknya tidak berhasil untuk pengganti rendah yang tak tertandingi.

Uji semua di browser Anda:


Bagaimana Anda membentuk karakter ini? Sepertinya setiap karakter adalah 4 byte.
user420667

2
@ user420667 karakter berasal dari bidang karakter tambahan (dalam tabel unicode) dengan codepoint "besar" karena itu mereka tidak masuk ke dalam 16 byte. Pengkodean utf-16 yang digunakan dalam javascript menyajikan karakter ini sebagai pasangan pengganti (karakter khusus yang hanya digunakan sebagai pasangan untuk membentuk karakter lain dari bidang tambahan). Hanya karakter pesawat charachter utama yang disajikan dengan 16 byte. Pasangan surrugate karakter khusus juga dari bidang karakter utama, jika masuk akal.
Olga

1
Performa dari teknik yang berbeda , spread op terlihat seperti champ (chrome 58).
Adrien

4
Perhatikan bahwa solusi ini membagi beberapa emoji seperti ๐Ÿณ๏ธโ€๐ŸŒˆ, dan membagi menggabungkan tanda diakritik dari karakter. Jika Anda ingin membagi ke dalam cluster grapheme alih-alih karakter, lihat stackoverflow.com/a/45238376 .
user202729

3
Perhatikan bahwa meskipun tidak mematahkan pasangan pengganti adalah hal yang baik, itu bukan solusi tujuan umum untuk menjaga "karakter" (atau lebih tepatnya, grapheme ) bersama-sama. Grapheme dapat terdiri dari beberapa titik kode; misalnya, nama bahasa Devanagari adalah "เคฆเฅ‡เคตเคจเคพเค—เคฐเฅ€", yang dibaca oleh penutur asli sebagai lima grafem, tetapi membutuhkan delapan titik kode untuk menghasilkan ...
TJ Crowder

71

The spreadSintaks

Anda dapat menggunakan sintaks spread , sebuah Initializer Array yang diperkenalkan dalam standar ECMAScript 2015 (ES6) :

var arr = [...str];

Contohnya

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

Tiga hasil pertama dalam:

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

Yang terakhir menghasilkan

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

Dukungan Browser

Periksa tabel kompatibilitas ECMAScript ES6 .


Bacaan lebih lanjut

spreadjuga dirujuk sebagai " splat" (mis. dalam PHP atau Ruby atau sebagai " scatter" (misalnya dalam Python ).


Demo

Coba sebelum membeli


1
Jika Anda menggunakan operator spread dalam kombinasi dengan compiler ke ES5 maka ini tidak akan berfungsi di IE. Pertimbangkan itu. Butuh waktu berjam-jam untuk mencari tahu apa masalahnya.
Stef van den Berg

14

Anda juga bisa menggunakan Array.from.

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

Metode ini telah diperkenalkan di ES6.

Referensi

Dari Array


10

Ini adalah pertanyaan lama tapi saya menemukan solusi lain yang belum terdaftar.

Anda dapat menggunakan fungsi Object.assign untuk mendapatkan hasil yang diinginkan:

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

Belum tentu benar atau salah, hanyalah pilihan lain.

Object.assign dijelaskan dengan baik di situs MDN.


2
Masih jauh untuk sampai ke sana Array.from("Hello, world").
TJ Crowder

@TJCrowder Itu jalan panjang untuk sampai ke[..."Hello, world"]
chharvey

@chharvey - Heh. :-)
TJ Crowder

9

Sudah:

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

Atau untuk versi yang lebih ramah browser, gunakan:

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


4
-1: tidak. Cobalah:alert("Hello world!" == ['H','e','l','l','o',' ','w','o','r','l','d'])
R. Martinho Fernandes

5
Maaf. Saya kira yang ingin saya katakan adalah: "Anda dapat mengakses karakter individu dengan referensi indeks seperti ini tanpa membuat array karakter".
dansimau

3
Tidak dapat diandalkan lintas-browser Anda tidak bisa. Ini adalah fitur Edisi Kelima ECMAScript.
bobince

8
Versi lintas-browser adalah mystring.charAt(index).
psmay

1
+1 untuk - charAt()walaupun saya lebih suka menggunakan varian array-ish. Darn IE.
Zenexer

4

Ada (setidaknya) tiga hal berbeda yang mungkin Anda bayangkan sebagai "karakter", dan akibatnya, tiga kategori pendekatan yang berbeda yang mungkin ingin Anda gunakan.

Membagi menjadi unit kode UTF-16

String JavaScript awalnya diciptakan sebagai urutan unit kode UTF-16, kembali pada suatu titik dalam sejarah ketika ada hubungan satu-ke-satu antara unit kode UTF-16 dan titik kode Unicode. The .lengthproperti string mengukur panjangnya di unit UTF-16 kode, dan ketika Anda melakukan someString[i]Anda mendapatkan i th UTF-16 kode unit darisomeString .

Akibatnya, Anda bisa mendapatkan array unit kode UTF-16 dari string dengan menggunakan C-style for-loop dengan variabel indeks ...

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

Ada juga berbagai cara singkat untuk mencapai hal yang sama, seperti menggunakan .split()dengan string kosong sebagai pemisah:

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

Namun, jika string Anda berisi titik kode yang terdiri dari beberapa unit kode UTF-16, ini akan membaginya menjadi unit kode individual, yang mungkin bukan yang Anda inginkan. Misalnya, string '๐Ÿ˜๐Ÿ™๐Ÿš๐Ÿ›'terdiri dari empat titik kode unicode (titik kode 0x1D7D8 hingga 0x1D7DB) yang, dalam UTF-16, masing-masing terdiri dari dua unit kode UTF-16. Jika kami membagi string itu menggunakan metode di atas, kami akan mendapatkan array delapan unit kode:

const yourString = '๐Ÿ˜๐Ÿ™๐Ÿš๐Ÿ›';
console.log('First code unit:', yourString[0]);
const charArray = yourString.split('');
console.log('charArray:', charArray);

Membagi menjadi Poin Kode Unicode

Jadi, mungkin kita ingin membagi string kita menjadi Poin Kode Unicode! Itu dimungkinkan karena ECMAScript 2015 menambahkan konsep iterable ke bahasa. String sekarang iterables, dan ketika Anda mengulanginya (misalnya dengan for...ofloop), Anda mendapatkan poin kode Unicode, bukan unit kode UTF-16:

const yourString = '๐Ÿ˜๐Ÿ™๐Ÿš๐Ÿ›';
const charArray = [];
for (const char of yourString) {
  charArray.push(char);
}
console.log(charArray);

Kita dapat mempersingkat penggunaan ini Array.from, yang beralih dari iterable yang diteruskan secara implisit:

const yourString = '๐Ÿ˜๐Ÿ™๐Ÿš๐Ÿ›';
const charArray = Array.from(yourString);
console.log(charArray);

Namun, poin kode unicode bukan hal terbesar yang mungkin yang mungkin bisa dianggap sebagai "karakter" baik . Beberapa contoh hal-hal yang dapat dianggap sebagai "karakter" tunggal tetapi terdiri dari beberapa titik kode meliputi:

  • Aksen karakter, jika aksen diterapkan dengan titik kode yang menggabungkan
  • Bendera
  • Beberapa emoji

Kita dapat melihat di bawah ini bahwa jika kita mencoba untuk mengubah string dengan karakter tersebut ke dalam array melalui mekanisme iterasi di atas, karakter tersebut akhirnya dipecah dalam array yang dihasilkan. (Jika salah satu karakter tidak ditampilkan di sistem Anda, di yourStringbawah ini terdiri dari huruf kapital A dengan aksen akut, diikuti oleh bendera Inggris, diikuti oleh wanita kulit hitam.)

const yourString = 'Aฬ๐Ÿ‡ฌ๐Ÿ‡ง๐Ÿ‘ฉ๐Ÿฟ';
const charArray = Array.from(yourString);
console.log(charArray);

Jika kita ingin menyimpan masing-masing sebagai satu item dalam array terakhir kita, maka kita perlu array grapheme , bukan titik kode.

Membagi menjadi grafem

JavaScript tidak memiliki dukungan bawaan untuk ini - setidaknya belum. Jadi kita membutuhkan pustaka yang memahami dan mengimplementasikan aturan Unicode untuk kombinasi poin kode apa yang membentuk suatu grafem. Untungnya, ada: graphling -splitter orling . Anda ingin menginstalnya dengan npm atau, jika Anda tidak menggunakan npm, unduh file index.js dan sajikan dengan<script> tag. Untuk demo ini, saya akan memuatnya dari jsDelivr.

grafem-splitter memberi kita GraphemeSplitterkelas dengan tiga metode: splitGraphemes, iterateGraphemes, dan countGraphemes. Secara alami, kami ingin splitGraphemes:

const splitter = new GraphemeSplitter();
const yourString = 'Aฬ๐Ÿ‡ฌ๐Ÿ‡ง๐Ÿ‘ฉ๐Ÿฟ';
const charArray = splitter.splitGraphemes(yourString);
console.log(charArray);
<script src="https://cdn.jsdelivr.net/npm/grapheme-splitter@1.0.4/index.js"></script>

Dan inilah kita - sebuah array dari tiga grapheme, yang mungkin adalah yang Anda inginkan.


2

Anda dapat mengulangi panjang tali dan mendorong karakter di setiap posisi :

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
Meskipun pendekatan ini sedikit lebih penting daripada deklaratif, ini adalah yang paling berkinerja terbaik di utas ini dan pantas mendapatkan lebih banyak cinta. Salah satu batasan untuk mengambil karakter pada string oleh posisi adalah ketika berurusan dengan karakter melewati Rencana Multilingual Dasar dalam unicode seperti emoji. "๐Ÿ˜ƒ".charAt(0)akan mengembalikan karakter yang tidak dapat digunakan
KyleMit

2
@KyleMit ini sepertinya hanya berlaku untuk input pendek. Menggunakan input yang lebih panjang membuat .split("")opsi tercepat lagi
Lux

1
Juga .split("")tampaknya sangat dioptimalkan dalam firefox. Sementara loop memiliki kinerja yang sama di chrome dan firefox split secara signifikan lebih cepat di firefox untuk input kecil dan besar.
Lux


0

Satu kemungkinan adalah yang berikutnya:

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

Bagaimana dengan ini?

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

@KyleMit ini tampaknya lebih cepat daripada untuk saya loop + push jsperf.com/string-to-character-array/3
ms dan

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.