Как вы получаете строку в массив символов в JavaScript? - PullRequest
311 голосов
/ 28 декабря 2010

Как получить строку в массив символов в JavaScript?

Я думаю получить строку типа "Hello world!" в массив ['H','e','l','l','o',' ','w','o','r','l','d','!']

Ответы [ 10 ]

440 голосов
/ 28 декабря 2010

Примечание. Это не соответствует юникоду. "I?U".split('') результатов в Массив из 4 символов ["I", "�", "�", "u"], который может привести к опасным ошибок. См. Ответы ниже для безопасных альтернатив.

Просто разделите его на пустую строку.

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

См. String.prototype.split() MDN документы .

222 голосов
/ 11 января 2016

Поскольку этот вопрос первоначально задавался более пяти лет назад, люди все еще неправильно вводят этот тип задачи. Как hippietrail предлагает , ответ медера может сломаться суррогатные пары и неверное толкование «символов». Например:

// DO NOT USE THIS!
> '????'.split('')
[ '�', '�', '�', '�', '�', '�', '�', '�' ]

Я предлагаю использовать одну из следующих функций ES2015 для правильной обработки этих последовательностей символов.

Spread-оператор ( уже ответил от имени пользователя вставки здесь)

> [...'????']
[ '?', '?', '?', '?' ]

Array.from

> Array.from('????')
[ '?', '?', '?', '?' ]

RegExp u флаг

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

Используйте /(?=[\s\S])/u вместо /(?=.)/u, поскольку . не соответствует символам новой строки .

Если вы все еще находитесь в эпохе ES5.1 (или если ваш браузер неправильно обрабатывает это регулярное выражение - например, Edge), вы можете использовать эту альтернативу (передано Babel ):

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

Обратите внимание, что Бабель также пытается правильно обрабатывать непревзойденных суррогатов. Тем не менее, это не работает для непревзойденных низких суррогатов.

Проверьте все в вашем браузере:

function run_test(){
  str=document.getElementById('nonBMP').checked ? '?_NL_?_HIGH_?_LOW_?' : '0_NL_1_HIGH_2_LOW_3';
  str=str.replace('_NL_'  ,document.getElementById('nl'  ).checked ? '\n'          : '');
  str=str.replace('_HIGH_',document.getElementById('high').checked ? '?'.charAt(0) : '');
  str=str.replace('_LOW_' ,document.getElementById('low' ).checked ? '?'.charAt(1) : '');
  
  //wrap all examples into try{ eval(...) } catch {} to aloow script execution if some syntax not supported (for example in Internet Explorer)
        document.getElementById("testString"   ).innerText=JSON.stringify(str);
  try { document.getElementById("splitEmpty"   ).innerText=JSON.stringify(eval('str.split("")'));            } catch(err) { }
  try { document.getElementById("splitRegexDot").innerText=JSON.stringify(eval('str.split(/(?=.)/u)'));      } catch(err) { }
  try { document.getElementById("spread"       ).innerText=JSON.stringify(eval('[...str]'));                 } catch(err) { }
  try { document.getElementById("arrayFrom"    ).innerText=JSON.stringify(eval('Array.from(str)'));          } catch(err) { }
  try { document.getElementById("splitRegex"   ).innerText=JSON.stringify(eval('str.split(/(?=[\\s\\S])/u)')); } catch(err) { }
  try { document.getElementById("splitBabel"   ).innerText=JSON.stringify(eval('str.split(/(?=(?:[\\0-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]))/)')); } catch(err) { }
}


document.getElementById('runTest').onclick=run_test;
th, td {
    border: 1px solid black;
    padding: 4px;
}
<div><input type="checkbox" id="nonBMP" checked /><label for="nonBMP">Codepoints above U+FFFF</label></div>
<div><input type="checkbox" id="nl"     checked /><label for="nl"    >Newline</label></div>
<div><input type="checkbox" id="high"           /><label for="high"  >Unmached high surrogate</label></div>
<div><input type="checkbox" id="low"            /><label for="low"   >Unmached low surrogate</label></div>
<button type="button" id="runTest">Run Test!</button>

<table>
  <tr><td>str=</td>                     <td><div id="testString"></div></td></tr>
  <tr><th colspan="2">Wrong:</th></tr>
  <tr><td>str.split("")</td>            <td><div id="splitEmpty"></div></td></tr>
  <tr><td>str.split(/(?=.)/u)</td>      <td><div id="splitRegexDot"></div></td></tr>
  <tr><th colspan="2">Better:</th></tr>
  <tr><td>[...str]</td>                 <td><div id="spread"></div></td></tr>
  <tr><td>Array.from(str)</td>          <td><div id="arrayFrom"></div></td></tr>
  <tr><td>str.split(/(?=[\s\S])/u)</td> <td><div id="splitRegex"></div></td></tr>
  <tr><td>str.split(/(?=(?:[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))/)</td><td><div id="splitBabel"></div></td></tr>
</table>
58 голосов
/ 20 октября 2015

Синтаксис 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);

Первые три результата:

["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 ).


Демо

Попробуйте перед покупкой

10 голосов
/ 28 декабря 2010

Это уже есть:

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'
8 голосов
/ 13 октября 2016

Вы также можете использовать Array.from.

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

Этот метод был введен в ES6.

Ссылки

Array.from

5 голосов
/ 12 апреля 2016

Это старый вопрос, но я столкнулся с другим решением, которого еще нет в списке.

Вы можете использовать функцию Object.assign для получения желаемого результата:

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

Не обязательно правильно или неправильно, просто другой вариант.

Object.assign хорошо описан на сайте MDN.

3 голосов
/ 28 июня 2016

Вы можете перебрать всю длину строки и нажать символ в каждой позиции :

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 голос
/ 25 мая 2019

простой ответ:

let str = 'this is string, length is >26';

console.log([...str]);
0 голосов
/ 01 апреля 2019

Как насчет этого?

function stringToArray(string) {
  let length = string.length;
  let array = new Array(length);
  while (length--) {
    array[length] = string[length];
  }
  return array;
}
0 голосов
/ 08 января 2019

Array Map также является хорошим вариантом

const name = "Hello World !"
const map = Array.prototype.map
const arr = map.call(name, single => {
    return `${single}`
})

console.log(arr) 
...