pq0usg
Last Updated: April 08, 2016
·
4.342K
· gaqzi
85570b6623e44f128c08668bf6687f85

Javascript String.split that'll return the remainder

In other languages I use String.splits' limit argument usually means, "split this string this many times, and put any remainder as the last array index". In Javascript however anything past the limit split is just discarded.

Example:

 /* A function that splits a string `limit` times and adds the remainder as a final array index. 
  * > var a = 'convoluted.madeup.example';
  * > a.split('.', 1);
  * < ['convoluted']
  * // What I expected:
  * < ['convoluted', 'madeup.example']
  */
function split(str, separator, limit) {
    str = str.split(separator);

    if(str.length > limit) {
        var ret = str.splice(0, limit);
        ret.push(str.join(separator));

        return ret;
    }

    return str;
}
Say Thanks
Respond

6 Responses
Add your response

311
Ebc47ee771e1695743e6b79c0821f37f

I think you have a bug, str.splice(0, limit) doesn't manipulate str in place. If you want to put the remainder rather than the whole thing as the last item you'll need something like:

str = str.splice(limit, str.length)

before the return.

over 1 year ago ·
316
85570b6623e44f128c08668bf6687f85

splice changes the array in place, if it removes it'll return the items removed.

With the test cases I've had I've gotten out the results I want, so while I don't deny the possibility of a bug it's not in my current test cases.

Test cases being:
split('convoluted.madeup.example.with.more.stuff', '.', 1) => ["convoluted", "madeup.example.with.more.stuff"]
split("hello-do-nothing-with-me-except-an-array", '.', 1) => ["hello-do-nothing-with-me-except-an-array"]
split("first.second-but-also-the-remainder-even-if-more-mightve-been", '.', 3) =>
["first", "second-but-also-the-remainder-even-if-more-mightve-been"]

over 1 year ago ·
325
Ebc47ee771e1695743e6b79c0821f37f

Oh I'm completely mistaken, I could've sworn I saw that when I tested that in the console, but you are right.

over 1 year ago ·
326
Ebc47ee771e1695743e6b79c0821f37f

Btw it seems to me like you only need one condition, since the other two does the same thing:

function split(str, separator, limit) {
    str = str.split(separator);

    if(str.length > limit) {
        var ret = str.splice(0, limit);
        ret.push(str.join(separator));

        return ret;
    }
    return str;
}

which I would've turned into an if guard instead (whichever is your preference):

function split(str, separator, limit) {
    str = str.split(separator);
    if(str.length <= limit) return str;

    var ret = str.splice(0, limit);
    ret.push(str.join(separator));

    return ret;
}
over 1 year ago ·
335
85570b6623e44f128c08668bf6687f85

Haha, that's a very good catch. A really silly if there. :)

over 1 year ago ·
27488

here is another implementation:
function split2(str, separator, limit) {
if (limit==0) return [str];
var a = str.split(separator, limit);
if(a.length == limit) {
let s = a.join(separator) + separator;
a.push( str.substr(s.length) );
return a;
}else{
return [str];
}
}

this way you don't have to split the entire string (in case it is huge), also shouldn't the function always return an array?

over 1 year ago ·