正如标题所说,我有一个字符串,我想把它分成n个字符的片段。
例如:
var str = 'abcdefghijkl';
当n=3时,它会变成
var arr = ['abc','def','ghi','jkl'];
有办法做到这一点吗?
正如标题所说,我有一个字符串,我想把它分成n个字符的片段。
例如:
var str = 'abcdefghijkl';
当n=3时,它会变成
var arr = ['abc','def','ghi','jkl'];
有办法做到这一点吗?
当前回答
稍后再讨论,但这里有一个变化,比子字符串+数组push 1快一点。
// substring + array push + end precalc
var chunks = [];
for (var i = 0, e = 3, charsLength = str.length; i < charsLength; i += 3, e += 3) {
chunks.push(str.substring(i, e));
}
作为for循环的一部分,预先计算结束值比在子字符串中进行内联计算要快。我已经在Firefox和Chrome上测试过了,它们都显示了加速。
你可以在这里试试
其他回答
我的解决方案(ES6语法):
const source = "8d7f66a9273fc766cd66d1d";
const target = [];
for (
const array = Array.from(source);
array.length;
target.push(array.splice(0,2).join(''), 2));
我们甚至可以这样创建一个函数:
function splitStringBySegmentLength(source, segmentLength) {
if (!segmentLength || segmentLength < 1) throw Error('Segment length must be defined and greater than/equal to 1');
const target = [];
for (
const array = Array.from(source);
array.length;
target.push(array.splice(0,segmentLength).join('')));
return target;
}
然后你可以以一种可重用的方式轻松地调用函数:
const source = "8d7f66a9273fc766cd66d1d";
const target = splitStringBySegmentLength(source, 2);
干杯
一些不使用正则表达式的干净解决方案:
/**
* Create array with maximum chunk length = maxPartSize
* It work safe also for shorter strings than part size
**/
function convertStringToArray(str, maxPartSize){
const chunkArr = [];
let leftStr = str;
do {
chunkArr.push(leftStr.substring(0, maxPartSize));
leftStr = leftStr.substring(maxPartSize, leftStr.length);
} while (leftStr.length > 0);
return chunkArr;
};
使用示例—https://jsfiddle.net/maciejsikora/b6xppj4q/。
我还尝试将我的解决方案与被选为正确答案的regexp进行比较。可以在jsfiddle - https://jsfiddle.net/maciejsikora/2envahrk/上找到一些测试。测试表明这两种方法具有相似的性能,可能乍一看regexp解决方案稍微快一点,但请自行判断。
我最喜欢的答案是gouder hicham的。但我稍微修改了一下,让它更有意义。
let myString = "Able was I ere I saw elba";
let splitString = [];
for (let i = 0; i < myString.length; i = i + 3) {
splitString.push(myString.slice(i, i + 3));
}
console.log(splitString);
下面是该代码的一个功能化版本。
function stringSplitter(myString, chunkSize) {
let splitString = [];
for (let i = 0; i < myString.length; i = i + chunkSize) {
splitString.push(myString.slice(i, i + chunkSize));
}
return splitString;
}
以及函数的用法:
let myString = "Able was I ere I saw elba";
let mySplitString = stringSplitter(myString, 3);
console.log(mySplitString);
结果是:
>(9) ['Abl', 'e w', 'as ', 'I e', 're ', 'I s', 'aw ', 'elb', 'a']
这里有一种不需要正则表达式或显式循环的方法,尽管它有点扩展了一行代码的定义:
const input = 'abcdefghijlkm';
// Change `3` to the desired split length.
const output = input.split('').reduce((s, c) => {
let l = s.length-1;
(s[l] && s[l].length < 3) ? s[l] += c : s.push(c);
return s;
}, []);
console.log(output); // output: [ 'abc', 'def', 'ghi', 'jlk', 'm' ]
它的工作原理是将字符串分割为单个字符的数组,然后使用array。还原遍历每个字符。通常情况下,reduce会返回一个值,但在这种情况下,这个值恰好是一个数组,当我们传递每个字符时,我们将它附加到该数组的最后一项。一旦数组中的最后一项达到目标长度,就追加一个新的数组项。
如果你真的需要坚持使用.split和/或.raplace,那么使用/(?<=^(?:.{3})+)(?!$)/g
.split:
var arr = str.split( /(?<=^(?:.{3})+)(?!$)/ )
// [ 'abc', 'def', 'ghi', 'jkl' ]
.replace:
var replaced = str.replace( /(?<=^(?:.{3})+)(?!$)/g, ' || ' )
// 'abc || def || ghi || jkl'
/(?!$)/表示在字符串结束时不停止。没有它的:
var arr = str.split( /(?<=^(?:.{3})+)/ )
// [ 'abc', 'def', 'ghi', 'jkl' ] // is fine
var replaced = str.replace( /(?<=^(.{3})+)/g, ' || ')
// 'abc || def || ghi || jkl || ' // not fine
忽略组/(?:…)/是为了防止数组中存在重复项。没有它的:
var arr = str.split( /(?<=^(.{3})+)(?!$)/ )
// [ 'abc', 'abc', 'def', 'abc', 'ghi', 'abc', 'jkl' ] // not fine
var replaced = str.replace( /(?<=^(.{3})+)(?!$)/g, ' || ' )
// 'abc || def || ghi || jkl' // is fine