28

I would like to split a string into fixed-length (N, for example) pieces. Of course, last piece could be shorter, if original string's length is not multiple of N.

I need the fastest method to do it, but also the simplest to write. The way I have been doing it until now is the following:

var a = 'aaaabbbbccccee';
var b = [];
for(var i = 4; i < a.length; i += 4){ // length 4, for example
    b.push(a.slice(i-4, i));
}
b.push(a.slice(a.length - (4 - a.length % 4))); // last fragment

I think there must be a better way to do what I want. But I don't want extra modules or libraries, just simple JavaScript if it's possible.

Before ask, I have seen some solutions to resolve this problem using other languages, but they are not designed with JavaScript in mind.

8
  • Do you really write all that out everytime just to avoid a function call? Commented May 6, 2012 at 23:04
  • What makes you think that you can have fastest code execution and simplicity of implementation? Those two qualities are often competing. Commented May 6, 2012 at 23:05
  • 1
    Here is another implementation, but still very similar to yours: phpjs.org/functions/str_split:530 Commented May 6, 2012 at 23:05
  • @Esailija He said that somewhere? @sgmonda I don't think there is much better way. As javascript string does not have a method to do this, few lines of code like you have are fine. And this should be fast enough too. Commented May 6, 2012 at 23:07
  • 1
    @Imp I don't know any other explanation for it needing to have a requirement to be easy to write other than writing it out every time. It wouldn't matter if it's very optimized but ugly code behind a function you just call. Commented May 6, 2012 at 23:09

3 Answers 3

49

You can try this:

var a = 'aaaabbbbccccee';
var b = a.match(/(.{1,4})/g);
Sign up to request clarification or add additional context in comments.

8 Comments

Very simple! I like it! But what happens if fixed-lenght is 32, for example? I would have to write /(.{32}|.{31}|.{30}...|.{2}|.)/g. Too text!
Even shorter: a.match(/(.{1,4})/g);
I'd probably use [\S\s] or similar over . as it includes every character
Perfect, @Niko! Just what I was looking for.
Sorry guys, I tried to edit this post before and write the same idea that @Niko had, but I don't know why, I couldn't
|
9

See this related question: https://stackoverflow.com/a/10456644/711085 and https://stackoverflow.com/a/8495740/711085 (See performance test in comments if performance is an issue.)

First (slower) link:

[].concat.apply([],
    a.split('').map(function(x,i){ return i%4 ? [] : a.slice(i,i+4) })
)

As a string prototype:

String.prototype.chunk = function(size) {
    return [].concat.apply([],
        this.split('').map(function(x,i){ return i%size ? [] : this.slice(i,i+size) }, this)
    )
}

Demo:

> '123412341234123412'.chunk(4)
["1234", "1234", "1234", "1234", "12"]

3 Comments

Now that the regex answer does not require writing /(.{32}|.{31}|.{30}............................|.{2}|.)/g, I would have to recommend that answer since it very concise. =) This solution is better only for chunking arrays.
This seems perfect for the same problem but applied to arrays. Thank you! For spliting strings I prefer the above solution.
@FelixKling: Ah interesting. Though one should not take the test to imply (probably incorrectly) that Array.concat is slow. The most likely culprit is 1) the conversion to an array (testable by doing .split('') in preparation code), and 2) performing an unnecessary 4x if statements. Nevertheless the for-loop version is definitely going to be more efficient; I was undecided which of the two answers I should link. Thanks, I'll edit to point this out.
1
function stringToChanks(string, chunkSize) {
    const chunks = [];
    while (string.length > 0) {
        chunks.push(string.substring(0, chunkSize));
        string = string.substring(chunkSize, string.length);
    }
    return chunks
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.