Làm thế nào để bạn có được một chuỗi đến một mảng ký tự trong JavaScript?


369

Làm thế nào để bạn chuyển đổi một chuỗi thành một mảng ký tự trong JavaScript?

Tôi nghĩ rằng có được một chuỗi như "Hello world!"mảng
['H','e','l','l','o',' ','w','o','r','l','d','!']

Câu trả lời:


492

Lưu ý: Đây không phải là tuân thủ unicode. dẫn đến "I💖U".split('')mảng 4 ký tự ["I", "�", "�", "u"]có thể dẫn đến các lỗi nguy hiểm. Xem câu trả lời dưới đây để thay thế an toàn.

Chỉ cần tách nó bằng một chuỗi rỗng.

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

Xem String.prototype.split()tài liệu MDN .


31
Điều này không tính đến các cặp thay thế. "𨭎".split('')kết quả trong ["�", "�"].
hà mã

59
Xem câu trả lời của @ hakatashi ở nơi khác trong chủ đề này. Hy vọng mọi người nhìn thấy điều này ... ĐỪNG SỬ DỤNG PHƯƠNG PHÁP NÀY, KHÔNG PHẢI LÀ UNICODE AN TOÀN
i336_

3
Bit đến bữa tiệc muộn. Nhưng tại sao ai đó muốn tạo ra một chuỗi của một chuỗi? Một chuỗi đã là một mảng hoặc tôi sai? "randomstring".length; //12 "randomstring"[2]; //"n"
Luigi van der Pal

4
@LuigivanderPal Một chuỗi không phải là một mảng, nhưng nó rất giống nhau. Tuy nhiên, nó không giống với một mảng các ký tự. Một chuỗi tương tự như một mảng gồm các số 16 bit, một số trong đó đại diện cho các ký tự và một số trong đó đại diện cho một nửa của cặp thay thế. Ví dụ: str.lengthkhông cho bạn biết số lượng ký tự trong chuỗi, vì một số ký tự chiếm nhiều không gian hơn các ký tự khác; str.lengthcho bạn biết số lượng các số 16 bit.
Theodore Norvell

289

Như hà mã gợi ý , câu trả lời của người trung gian có thể phá vỡ các cặp thay thế và giải thích sai các ký tự. Ví dụ:

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

Tôi đề nghị sử dụng một trong các tính năng ES2015 sau đây để xử lý chính xác các chuỗi ký tự này.

Cú pháp lây lan ( đã được trả lời bởi insertusernamehere)

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

Array.from

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

uCờ RegExp

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

Sử dụng /(?=[\s\S])/uthay /(?=.)/uvì vì .không phù hợp với dòng mới .

Nếu bạn vẫn ở thời đại ES5.1 (hoặc nếu trình duyệt của bạn không xử lý chính xác biểu thức chính này - như Edge), bạn có thể sử dụng giải pháp thay thế này (được dịch bởi Babel ):

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

Lưu ý rằng Babel cũng cố gắng xử lý chính xác những người thay thế chưa từng có. Tuy nhiên, điều này dường như không hoạt động đối với những người thay thế thấp chưa từng có.

Kiểm tra tất cả trong trình duyệt của bạn:


Làm thế nào bạn hình thành những nhân vật này? Dường như mỗi ký tự là 4 byte.
user420667

2
@ user420667 các ký tự được lấy từ một mặt phẳng ký tự bổ sung (trong bảng unicode) với các điểm mã "lớn" do đó chúng không khớp với 16 byte. Mã hóa utf-16 được sử dụng trong javascript trình bày các ký tự này dưới dạng các cặp thay thế (các ký tự đặc biệt chỉ được sử dụng làm cặp để tạo thành các ký tự khác từ các mặt phẳng bổ sung). Chỉ các ký tự trong mặt phẳng charachter chính được trình bày với 16 byte. Cặp nhân vật đặc biệt cũng xuất hiện từ mặt phẳng nhân vật chính, nếu nó có ý nghĩa.
Olga

1
Hiệu suất của các kỹ thuật khác nhau , trải op trông giống như champ (chrome 58).
Adrien

4
Lưu ý rằng giải pháp này phân tách một số biểu tượng cảm xúc 🏳️‍🌈, và chia tách kết hợp dấu phụ từ ký tự. Nếu bạn muốn chia thành các cụm grapheme thay vì các ký tự, hãy xem stackoverflow.com/a/45238376 .
dùng202729

3
Lưu ý rằng mặc dù không phá vỡ các cặp thay thế là tuyệt vời, nhưng đó không phải là một giải pháp cho mục đích chung để giữ các "ký tự" (hay chính xác hơn là đồ thị ) cùng nhau. Một grapheme có thể được tạo thành từ nhiều điểm mã; ví dụ, tên của ngôn ngữ Devanagari là "देवनागरी", được người bản ngữ đọc thành năm biểu đồ, nhưng lấy tám điểm mã để tạo ra ...
TJ Crowder

71

các spreadcú pháp

Bạn có thể sử dụng cú pháp lây lan , Bộ khởi tạo mảng được giới thiệu trong tiêu chuẩn ECMAScript 2015 (ES6) :

var arr = [...str];

Ví dụ

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

Ba kết quả đầu tiên trong:

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

Kết quả cuối cùng trong

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

Hỗ trợ trình duyệt

Kiểm tra bảng tương thích ECMAScript ES6 .


đọc thêm

spreadcũng được tham chiếu là " splat" (ví dụ: trong PHP hoặc Ruby hoặc là " scatter" (ví dụ: trong Python ).


Bản giới thiệu

Hãy thử trước khi mua


1
Nếu bạn sử dụng toán tử trải rộng kết hợp với trình biên dịch sang ES5 thì điều này sẽ không hoạt động trong IE. Hãy xem xét điều đó. Tôi đã mất nhiều giờ để tìm ra vấn đề là gì.
Stef van den Berg

13

Bạn cũng có thể sử dụng Array.from.

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

Phương pháp này đã được giới thiệu trong ES6.

Tài liệu tham khảo

Array.from


10

Đây là một câu hỏi cũ nhưng tôi đã đi qua một giải pháp khác chưa được liệt kê.

Bạn có thể sử dụng hàm Object.assign để có đầu ra mong muốn:

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

Không nhất thiết đúng hay sai, chỉ là một lựa chọn khác.

Object.assign được mô tả tốt tại trang MDN.


2
Đó là một chặng đường dài để đi đến Array.from("Hello, world").
TJ Crowder

@TJCrowder Đó là một chặng đường dài để đến[..."Hello, world"]
chharvey

@chharvey - Heh. :-)
TJ Crowder

9

Nó đã là:

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

Hoặc đối với phiên bản thân thiện với trình duyệt cũ hơn, hãy sử dụng:

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


4
-1: không phải vậy. Hãy thử:alert("Hello world!" == ['H','e','l','l','o',' ','w','o','r','l','d'])
R. Martinho Fernandes

4
Lấy làm tiếc. Tôi đoán điều tôi muốn nói là: "bạn có thể truy cập từng ký tự bằng cách tham chiếu chỉ mục như thế này mà không cần tạo một mảng ký tự".
dansimau

3
Không đáng tin cậy trên nhiều trình duyệt, bạn không thể. Đây là một tính năng ECMAScript Fifth Edition.
bobince

8
Phiên bản trình duyệt chéo là mystring.charAt(index).
psmay

1
+1 cho - charAt()mặc dù tôi muốn sử dụng biến thể mảng-ish. Chết tiệt IE.
Zenexer

4

Có (ít nhất) ba thứ khác nhau mà bạn có thể nghĩ là "nhân vật", và do đó, ba loại phương pháp khác nhau mà bạn có thể muốn sử dụng.

Chia thành các đơn vị mã UTF-16

Các chuỗi JavaScript ban đầu được phát minh dưới dạng chuỗi các đơn vị mã UTF-16, quay lại một điểm trong lịch sử khi có mối quan hệ một-một giữa các đơn vị mã UTF-16 và các điểm mã Unicode. Các .lengthtài sản của một chuỗi đo chiều dài của nó trong UTF-16 đơn vị mã, và khi bạn làm điều someString[i]bạn nhận được i thứ đơn vị mã UTF-16 someString.

Do đó, bạn có thể nhận được một mảng các đơn vị mã UTF-16 từ một chuỗi bằng cách sử dụng vòng lặp kiểu C với một biến chỉ mục ...

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

Ngoài ra còn có nhiều cách ngắn khác nhau để đạt được điều tương tự, như sử dụng .split()với chuỗi rỗng làm dấu phân cách:

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

Tuy nhiên, nếu chuỗi của bạn chứa các điểm mã được tạo thành từ nhiều đơn vị mã UTF-16, thì chuỗi này sẽ chia chúng thành các đơn vị mã riêng lẻ, có thể không phải là điều bạn muốn. Chẳng hạn, chuỗi '𝟘𝟙𝟚𝟛'được tạo thành từ bốn điểm mã unicode (điểm mã 0x1D7D8 đến 0x1D7DB), trong UTF-16, mỗi điểm được tạo thành từ hai đơn vị mã UTF-16. Nếu chúng ta chia chuỗi đó bằng các phương thức trên, chúng ta sẽ nhận được một mảng gồm tám đơn vị mã:

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

Chia thành các điểm mã Unicode

Vì vậy, có lẽ chúng tôi muốn chia chuỗi của chúng tôi thành Điểm Mã Unicode! Điều đó là có thể kể từ khi ECMAScript 2015 bổ sung khái niệm lặp lại cho ngôn ngữ. Các chuỗi bây giờ là các for...ofvòng lặp và khi bạn lặp lại chúng (ví dụ với một vòng lặp), bạn sẽ nhận được các điểm mã Unicode, không phải các đơn vị mã UTF-16:

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

Chúng ta có thể rút ngắn điều này bằng cách sử dụng Array.from, lặp đi lặp lại qua lần lặp mà nó được thông qua hoàn toàn:

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

Tuy nhiên, điểm mã unicode không phải là điều lớn nhất có thể mà có thể được coi là một "nhân vật" trong hai . Một số ví dụ về những thứ có thể được coi là một "ký tự" hợp lý nhưng được tạo thành từ nhiều điểm mã bao gồm:

  • Ký tự có dấu, nếu dấu được áp dụng với điểm mã kết hợp
  • Cờ
  • Một số biểu tượng cảm xúc

Chúng ta có thể thấy bên dưới rằng nếu chúng ta cố gắng chuyển đổi một chuỗi có các ký tự như vậy thành một mảng thông qua cơ chế lặp ở trên, các ký tự sẽ bị phá vỡ trong mảng kết quả. (Trong trường hợp bất kỳ nhân vật nào không hiển thị trên hệ thống của bạn, yourStringbên dưới bao gồm một chữ A có dấu trọng âm, theo sau là cờ của Vương quốc Anh, theo sau là một phụ nữ da đen.)

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

Nếu chúng ta muốn giữ mỗi thứ này như một mục duy nhất trong mảng cuối cùng của chúng ta, thì chúng ta cần một mảng các biểu đồ , không phải các điểm mã.

Chia thành đồ thị

JavaScript không có hỗ trợ tích hợp cho việc này - ít nhất là chưa. Vì vậy, chúng ta cần một thư viện hiểu và thực hiện các quy tắc Unicode cho sự kết hợp các điểm mã nào tạo thành một biểu đồ. May mắn thay, người ta tồn tại: bộ tách đồ thị của orling . Bạn sẽ muốn cài đặt nó với npm hoặc, nếu bạn không sử dụng npm, hãy tải xuống tệp index.js và cung cấp nó với một <script>thẻ. Đối với bản demo này, tôi sẽ tải nó từ jsDelivr.

grapheme-splitter cho chúng ta một GraphemeSplitterlớp học với ba phương pháp: splitGraphemes, iterateGraphemes, và countGraphemes. Đương nhiên, chúng tôi muốn 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>

Và chúng tôi ở đó - một mảng gồm ba biểu đồ, có lẽ là những gì bạn muốn.


2

Bạn có thể lặp theo chiều dài của chuỗi và đẩy ký tự ở mỗi vị trí :

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
Mặc dù cách tiếp cận này là bắt buộc hơn một chút so với tuyên bố, nhưng nó là hiệu suất cao nhất của bất kỳ trong chủ đề này và xứng đáng được yêu thích nhiều hơn. Một hạn chế để truy xuất một ký tự trên một chuỗi theo vị trí là khi xử lý các ký tự qua Kế hoạch đa ngôn ngữ cơ bản ở dạng unicode như biểu tượng cảm xúc. "😃".charAt(0)sẽ trả lại một nhân vật không thể sử dụng
KyleMit

2
@KyleMit điều này dường như chỉ đúng với một đầu vào ngắn. Sử dụng đầu vào dài hơn sẽ khiến .split("")tùy chọn nhanh nhất trở lại
Lux

1
Cũng .split("")có vẻ được tối ưu hóa mạnh mẽ trong firefox. Trong khi vòng lặp có hiệu suất tương tự trong chrome và phân chia firefox nhanh hơn đáng kể trong firefox cho các đầu vào nhỏ và lớn.
Lux


0

Một khả năng là tiếp theo:

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

Còn cái này thì sao?

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

@KyleMit điều này có vẻ nhanh hơn so với vòng lặp của tôi + đẩy jsperf.com/opes-to-character-array/3
msand

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.