如何在JavaScript中获取字符串数组的字符串?

Dar*_*htA 335 javascript arrays string character-arrays

如何在JavaScript中获取字符串数组的字符串?

我在想一个像"Hello world!"数组一样的字符串['H','e','l','l','o',' ','w','o','r','l','d','!']

med*_*iev 457

var output = "Hello world!".split('');
console.log(output);
Run Code Online (Sandbox Code Playgroud)

只需将其拆分为空字符串即可.

请参阅"IU".split('')MDN文档.

  • 请参阅@ hakatashi在此主题其他地方的答案.希望每个人都看到这个...***不要使用这种方法,它不是UNICODE安全*** (52认同)
  • 这不考虑代理对.`"".split('')`导致`[" "," "]`. (29认同)
  • 什么是你的解决方案,@ hippietrail? (4认同)
  • 晚会有点晚。但是,为什么有人要组成一个字符串数组呢?字符串已经是数组,还是我错了?`“ randomstring” .length;``// 12``“ randomstring” [2];``//“ n”` (3认同)
  • @LuigivanderPal字符串不是数组,但是非常相似。但是,它与字符数组不同。字符串类似于由16位数字组成的数组,其中一些代表字符,另一些代表代理对的一半。例如,“ str.length”不会告诉您字符串中的字符数,因为某些字符比其他字符占用更多的空间;str.length告诉您16位数字的数量。 (3认同)
  • (哇,这很有趣)@RayFoss:正如我指出的,要知道何时按下触发器并进行编辑可能很棘手。在这种情况下,很容易看出善意的意图(最上层+公认的答案被打破,并且通过指数投票确保线程完全被阻塞。)编辑后的注释似乎对整体而言是认真而周到的,这很好(并对你有利:))。另外,在提及归因时,我指的是保留原始文本,以将答案质量/正确性归因于其下方的用户名。干杯! (2认同)

hak*_*shi 251

由于这个问题最初是在五年多前提出的,人们仍然在误操作这类任务.正如hippietrail建议的那样,meder的答案可以打破代理对并误解"角色".例如:

// DO NOT USE THIS!
> ''.split('')
[ '?', '?', '?', '?', '?', '?', '?', '?' ]
Run Code Online (Sandbox Code Playgroud)

我建议使用以下ES2015功能之一来正确处理这些字符序列.

Spread-operator(已由insertusernamehere 回答)

> [...'']
[ '', '', '', '' ]
Run Code Online (Sandbox Code Playgroud)

Array.from

> Array.from('')
[ '', '', '', '' ]
Run Code Online (Sandbox Code Playgroud)

RegExp u标志

> ''.split(/(?=[\s\S])/u)
[ '', '', '', '' ]
Run Code Online (Sandbox Code Playgroud)

使用/(?=[\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]))/);
[ '', '', '', '' ]
Run Code Online (Sandbox Code Playgroud)

请注意,Babel试图正确处理不匹配的代理.然而,这似乎不适用于无与伦比的低代理人.

在浏览器中测试所有内容:

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;
Run Code Online (Sandbox Code Playgroud)
th, td {
    border: 1px solid black;
    padding: 4px;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 抱歉,“ misopetate”是什么意思?我用谷歌搜索,没有结果。我不确定这是什么错字(如果是错字),所以我不能自己编辑。 (4认同)
  • 请注意,此解决方案拆分了一些表情符号(如“ ️‍”),并拆分了组合变音符号和字符的符号。如果要拆分成字素簇而不是字符,请参阅/sf/answers/3166686351/。 (3认同)
  • Mozilla 官方文档引用了这个答案:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split (3认同)
  • @ user420667字符来自具有“大”代码点的附加字符平面(在unicode表中),因此它们不适合16个字节。javascript中使用的utf-16编码将这些字符显示为代理对(特殊字符仅用作对,以形成其他平面中的其他字符)。仅主字符平面的字符以16个字节表示。Surrugate对特殊字符也来自主字符平面(如果有意义)。 (2认同)
  • s/misope**t**ating/misope**r?ating?如果[不是针对SO转发器]我认为你有[Googlewhackblatt](https://en.wikipedia.org/wiki/Googlewhack#Variations)(https://www.google.com/search? q =误操作&nfpr = 1&sa = X),但编程中有足够奇怪的词我想我会检查. (2认同)
  • 请注意,虽然不分开代理对非常好,但它不是将“字符”(或更准确地说,*字素*)保持在一起的通用解决方案。字素可以由多个代码点组成。例如,梵文语言梵文的名称为“देवनागरी”,母语为母语的人将其读作5个字素,但需要8个代码点才能产生... (2认同)

ins*_*ere 63

spread语法

您可以使用扩展语法,即ECMAScript 2015(ES6)标准中引入的Array Initializer :

var arr = [...str];
Run Code Online (Sandbox Code Playgroud)

例子

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);
Run Code Online (Sandbox Code Playgroud)

前三个结果是:

["H", "e", "l", "l", "o", " ", "W", "o", "r", "l", "d"]
Run Code Online (Sandbox Code Playgroud)

最后一个结果

{0: "H", 1: "e", 2: "l", 3: "l", 4: "o", 5: " ", 6: "W", 7: "o", 8: "r", 9: "l", 10: "d"}
Run Code Online (Sandbox Code Playgroud)

浏览器支持

检查ECMAScript ES6兼容性表.


进一步阅读

spread也被称为" splat"(例如在PHPRuby中或" scatter"(例如在Python中).


演示

买前先试试

  • 如果您将扩展运算符与 ES5 编译器结合使用,那么这在 IE 中将不起作用。考虑到这一点。我花了几个小时才弄清楚问题出在哪里。 (2认同)

Mar*_*ery 13

您可能将(至少)三种不同的事物视为“角色”,因此,您可能想要使用三种不同类别的方法。

拆分为 UTF-16 代码单元

JavaScript 字符串最初是作为 UTF-16 代码单元序列而发明的,可以追溯到历史上 UTF-16 代码单元和 Unicode 代码点之间存在一对一关系的时候。.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);
Run Code Online (Sandbox Code Playgroud)

还有各种简短的方法可以实现相同的目的,例如使用.split()空字符串作为分隔符:

const charArray = 'Hello, World!'.split('');
console.log(charArray);
Run Code Online (Sandbox Code Playgroud)

但是,如果您的字符串包含由多个 UTF-16 代码单元组成的代码点,这会将它们拆分为单独的代码单元,这可能不是您想要的。例如,字符串''由四个 unicode 代码点(代码点 0x1D7D8 到 0x1D7DB)组成,在 UTF-16 中,每个由两个 UTF-16 代码单元组成。如果我们使用上述方法拆分该字符串,我们将得到一个包含八个代码单元的数组:

const yourString = '';
console.log('First code unit:', yourString[0]);
const charArray = yourString.split('');
console.log('charArray:', charArray);
Run Code Online (Sandbox Code Playgroud)

拆分为 Unicode 代码点

因此,也许我们想要将字符串拆分为 Unicode 代码点!自从 ECMAScript 2015 向该语言添加可迭代的概念以来,这已经成为可能。字符串现在是可迭代的,当您对它们进行迭代时(例如使用for...of循环),您将获得 Unicode 代码点,而不是 UTF-16 代码单元:

const yourString = '';
const charArray = [];
for (const char of yourString) {
  charArray.push(char);
}
console.log(charArray);
Run Code Online (Sandbox Code Playgroud)

我们可以使用 来缩短它Array.from,它迭代它隐式传递的可迭代对象:

const yourString = '';
const charArray = Array.from(yourString);
console.log(charArray);
Run Code Online (Sandbox Code Playgroud)

然而,Unicode码点是不是也可能会被认为是一个“性格”最大可能的事情要么。可以合理地被视为单个“字符”但由多个代码点组成的一些示例包括:

  • 重音字符,如果重音与组合码点一起应用
  • 旗帜
  • 一些表情符号

我们可以在下面看到,如果我们尝试通过上面的迭代机制将具有此类字符的字符串转换为数组,则这些字符最终会在结果数组中分解。(如果任何字符未在您的系统上呈现,yourString下面由带有尖音符的大写字母A组成,后跟英国国旗,后跟一位黑人女性。)

const yourString = 'A?';
const charArray = Array.from(yourString);
console.log(charArray);
Run Code Online (Sandbox Code Playgroud)

如果我们想将这些中的每一个都作为我们最终数组中的一个项目,那么我们需要一个graphemes数组,而不是代码点。

拆分成字素

JavaScript 没有对此的内置支持 - 至少现在还没有。因此,我们需要一个库来理解和实现 Unicode 规则,以了解哪些代码点组合构成了一个字素。幸运的是,存在一个:orling 的 grapheme -splitter。您需要使用 npm 安装它,或者,如果您不使用 npm,请下载 index.js 文件并为其提供<script>标签。对于这个演示,我将从 jsDelivr 加载它。

字形分离器给了我们一个GraphemeSplitter班有三种方法:splitGraphemesiterateGraphemes,和countGraphemes。自然,我们想要splitGraphemes

const splitter = new GraphemeSplitter();
const yourString = 'A?';
const charArray = splitter.splitGraphemes(yourString);
console.log(charArray);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.jsdelivr.net/npm/grapheme-splitter@1.0.4/index.js"></script>
Run Code Online (Sandbox Code Playgroud)

我们就是这样 - 一个由三个字素组成的数组,这可能是你想要的。


dan*_*mau 10

它已经是:

var mystring = 'foobar';
console.log(mystring[0]); // Outputs 'f'
console.log(mystring[3]); // Outputs 'b'
Run Code Online (Sandbox Code Playgroud)

或者对于更旧的浏览器友好版本,请使用:

var mystring = 'foobar';
console.log(mystring.charAt(3)); // Outputs 'b'
Run Code Online (Sandbox Code Playgroud)

  • 跨浏览器版本是`mystring.charAt(index)`. (8认同)
  • 抱歉.我想我的意思是:"你可以通过像这样的索引引用来访问单个字符而不创建字符数组". (4认同)
  • 不可靠的跨浏览器你不能.这是ECMAScript第五版的功能. (3认同)
  • -1:不是.试一试:`alert("Hello world!"== ['H','e','l','l','o','','w','o','r',' L", 'D'])` (2认同)

Raj*_*esh 10

你也可以使用Array.from.

var m = "Hello world!";
console.log(Array.from(m))
Run Code Online (Sandbox Code Playgroud)

这种方法已在ES6中引入.

参考

Array.from


Dav*_*mas 8

这是一个老问题,但是我遇到了另一个未列出的解决方案。

您可以使用Object.assign函数获取所需的输出:

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

不一定是对还是错,只是另一种选择。

在MDN站点上很好地描述了Object.assign。

  • 要到达Array.from(“ Hello,world”)`还有很长的路要走。 (2认同)

Aam*_*imi 7

在 JavaScript 中将字符串转换为字符数组的四种方法:

const string = 'word';

// Option 1
string.split('');  // ['w', 'o', 'r', 'd']

// Option 2
[...string];  // ['w', 'o', 'r', 'd']

// Option 3
Array.from(string);  // ['w', 'o', 'r', 'd']

// Option 4
Object.assign([], string);  // ['w', 'o', 'r', 'd']
Run Code Online (Sandbox Code Playgroud)


Moh*_*fei 5

ES6 将字符串按字符拆分为数组的方法是使用扩展运算符。它简单又漂亮。

array = [...myString];
Run Code Online (Sandbox Code Playgroud)

例子: