仅在分隔符的前n次出现时拆分字符串

时间:2022-07-15 16:52:16

I'd like to split a string only the at the first n occurrences of a delimiter. I know, I could add them together using a loop, but isn't there a more straight forward approach?

我想仅在分隔符的前n次出现时拆分字符串。我知道,我可以使用循环将它们添加到一起,但是不是更直接的方法吗?

var string = 'Split this, but not this';    
var result = new Array('Split', 'this,', 'but not this');

17 个解决方案

#1


33  

As per MDN:

根据MDN:

string.split(separator, limit);

Update:

var string = 'Split this, but not this',
    arr = string.split(' '),
    result = arr.slice(0,2);

result.push(arr.slice(2).join(' ')); // ["Split", "this,", "but not this"]

Update version 2 (one slice shorter):

更新版本2(更短一片):

var string = 'Split this, but not this',
    arr = string.split(' '),
    result = arr.splice(0,2);

result.push(arr.join(' ')); // result is ["Split", "this,", "but not this"]

#2


16  

Using Array.slice:

function splitWithTail(str,delim,count){
  var parts = str.split(delim);
  var tail = parts.slice(count).join(delim);
  var result = parts.slice(0,count);
  result.push(tail);
  return result;
}

Results:

splitWithTail(string," ",2)
// => ["Split", "this,", "but not this"]

#3


6  

The JavaScript ".split()" function already accepts a second parameter giving the maximum number of splits to perform. However, it doesn't retain the tail end of your original string; you'd have to glue it back on.

JavaScript“.split()”函数已经接受第二个参数,给出要执行的最大拆分数。但是,它不会保留原始字符串的尾端;你必须重新粘上它。

Another approach would be to iteratively shave off a leading portion of the string with a regex, stopping when you've gotten your limit.

另一种方法是用正则表达式迭代地剪掉字符串的前导部分,当你获得限制时停止。

var str = "hello out there cruel world";
var parts = [];
while (parts.length < 3) { // "3" is just an example
  str = str.replace(/^(\w+)\s*(.*)$/, function(_, word, remainder) {
    parts.push(word);
    return remainder;
  });
}
parts.push(str);

edit — and it just occurs to me that another simple way would be to just use plain ".split()", pluck off the first few parts, and then just ".slice()" and ".join()" the rest.

编辑 - 它只是发生在我身上,另一个简单的方法是使用普通的“.split()”,取出前几个部分,然后只是“.slice()”和“.join()”其余部分。

#4


3  

For this you could use Split(delimiter) and choose a delimiter.

为此,您可以使用Split(分隔符)并选择分隔符。

var testSplit = "Split this, but not this";
var testParts= testSplit.Split(",");

var firstPart = testParts[1];

// firstPart = "Split this"

Not 100% on my syntax I havent used javascript in quite some time. But I know this is how its done...

我的语法不是100%我在很长一段时间没有使用过javascript。但我知道这是怎么做的......

EDIT** Sorry, my mistake. Now I believe I know what your asking and I think the easiest way to do this is using substr. Very easy, no loops required. Just made an example, works perfect

编辑**对不起,我的错误。现在我相信我知道你的要求,我认为最简单的方法就是使用substr。非常简单,无需循环。刚刚做了一个例子,工作完美

// so first, we want to get everything from 0 - the first occurence of the comma.
// next, we want to get everything after the first occurence of the comma.  (if you only define one parameter, substr will take everything after that parameter.

var testString = "Split this, but this part, and this part are one string";
var part1 = testString.substr(0,testString.indexOf(',')); 
var part2 = testString.substr(testString.indexOf(','));

//part1 = "Split this"
//part2= "but this part, and this part are one string"

#5


3  

Combination of split and join with ES6 features does this pretty neat:

分割和连接与ES6功能的结合使这非常简洁:

let [str1, str2, ...str3] = string.split(' ');
str3 = str3.join(' ');

#6


2  

Although you can give split a limit, you won't get back what you've said you want. Unfortunately, you will have to roll your own on this, e.g.:

虽然你可以给予分割限制,但你不会得到你所说的你想要的东西。不幸的是,你必须自己动手,例如:

var string = 'Split this, but not this';
var result = string.split(' ');

if (result.length > 3) {
    result[2] = result.slice(2).join(' ');
    result.length = 3;
}

But even then, you end up modifying the number of spaces in the latter parts of it. So I'd probably just do it the old-fashioned write-your-own-loop way:

但即便如此,您最终还是会修改后面部分的空格数。所以我可能只是采用老式的自编循环方式:

function splitWithLimit(str, delim, limit) {
  var index,
      lastIndex = 0,
      rv = [];

  while (--limit && (index = str.indexOf(delim, lastIndex)) >= 0) {
    rv.push(str.substring(lastIndex, index));
    lastIndex = index + delim.length;
  }
  if (lastIndex < str.length) {
    rv.push(str.substring(lastIndex));
  }
  return rv;
}

Live copy

#7


2  

var result = [string.split(' ',1).toString(), string.split(' ').slice(1).join(' ')];

Results in:

["Split", "this, but not this"]

#8


1  

Hi there i had the same problem wanted to split only several times, couldnt find anything so i just extended the DOM - just a quick and dirty solution but it works :)

嗨,我有同样的问题想分裂几次,无法找到任何东西,所以我只是扩展了DOM - 只是一个快速和肮脏的解决方案,但它的工作:)

String.prototype.split = function(seperator,limit) {
    var value = "";
    var hops  = [];

    // Validate limit
    limit = typeof(limit)==='number'?limit:0;

    // Join back given value
    for ( var i = 0; i < this.length; i++ ) { value += this[i]; }

    // Walkthrough given hops
    for ( var i = 0; i < limit; i++ ) {
        var pos = value.indexOf(seperator);
        if ( pos != -1 ) {
            hops.push(value.slice(0,pos));
            value = value.slice(pos + seperator.length,value.length)

        // Done here break dat
        } else {
            break;
        }
    }
    // Add non processed rest and return
    hops.push(value)
    return hops;
}

In your case would look like that

在你的情况下看起来像那样

>>> "Split this, but not this".split(' ',2)
["Split", "this,", "but not this"]

#9


1  

Improved version of a sane limit implementation with proper RegEx support:

通过适当的RegEx支持改进版本的理智限制实现:

function splitWithTail(value, separator, limit) {
    var pattern, startIndex, m, parts = [];

    if(!limit) {
        return value.split(separator);
    }

    if(separator instanceof RegExp) {
        pattern = new RegExp(separator.source, 'g' + (separator.ignoreCase ? 'i' : '') + (separator.multiline ? 'm' : ''));
    } else {
        pattern = new RegExp(separator.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'), 'g');
    }

    do {
        startIndex = pattern.lastIndex;
        if(m = pattern.exec(value)) {
            parts.push(value.substr(startIndex, m.index - startIndex));
        }
    } while(m && parts.length < limit - 1);
    parts.push(value.substr(pattern.lastIndex));

    return parts;
}

Usage example:

splitWithTail("foo, bar, baz", /,\s+/, 2); // -> ["foo", "bar, baz"]

Built for & tested in Chrome, Firefox, Safari, IE8+.

专为Chrome,Firefox,Safari,IE8 +而设计和测试。

#10


0  

var s='Split this, but not this', a=s.split(','), b=a[0].split(' ');
b.push(a[1]);
alert(b);

alerts ['Split', 'this', 'but not this']

提醒['拆分','这个','但不是这个']

#11


0  

Yet another implementation I just wrote:

我刚写的另一个实现:

export function split(subject, separator, limit=undefined, pad=undefined) {
    if(!limit) {
        return subject.split(separator);
    }
    if(limit < 0) {
        throw new Error(`limit must be non-negative`);
    }
    let result = [];
    let fromIndex = 0;
    for(let i=1; i<limit; ++i) {
        let sepIdx = subject.indexOf(separator, fromIndex);
        if(sepIdx < 0) {
            break;
        }
        let substr = subject.slice(fromIndex, sepIdx);
        result.push(substr);
        fromIndex = sepIdx + separator.length;
    }
    result.push(subject.slice(fromIndex));
    while(result.length < limit) {
        result.push(pad);
    }
    return result;
}

Doesn't use regexes, nor does it over-split and re-join.

不使用正则表达式,也不会过度拆分和重新加入。

This version guarantees exactly limit elements (will pad with undefineds if there aren't enough separators); this makes it safe to do this kind of ES6 stuff:

此版本保证精确限制元素(如果没有足够的分隔符,将填充未定义的);这样做可以安全地做这种ES6的东西:

let [a,b,c] = split('a$b','$',3,null);
// a = 'a', b = 'b', c = null

#12


0  

I like using shift.

我喜欢使用班次。

function splitFirstN(str,n,delim){
    var parts = str.split(delim);
    var r = [];
    for(var i = 0; i < n; i++){
        r.push(parts.shift());
    }
    r.push(parts.join(delim));
    return r;
}

var str = 'Split this, but not this';    
var result = splitFirstN(str,2,' ');

#13


0  

Nothing a one simple regex can't do:

没有一个简单的正则表达式不能做:

const string = 'Split this, but not this';
console.log(string.match(/^(\S+)\s*(\S+)?\s*([\s\S]+)?$/).slice(1));

#14


0  

In my case I was trying to parse git grep stdout. So I had a {filename}:{linenumber}:{context}. I don't like splitting and then joining. We should be able to parse the string one time. You could simply step through each letter and split on the first two colons. A quicker way to do it out of the box is by using the match method and regex.

在我的情况下,我试图解析git grep stdout。所以我有一个{filename}:{linenumber}:{context}。我不喜欢分裂然后加入。我们应该能够解析一次字符串。您可以简单地逐步浏览每个字母并分成前两个冒号。开箱即用的更快捷的方法是使用匹配方法和正则表达式。

Hence,

txt.match(/(.+):(\d+):(.*)/)

Works great

#15


0  

Yet another implementation with limit;

又一个有限制的实施;

// takes string input only
function split(input, separator, limit) {
    input = input.split(separator);
    if (limit) {
        input = input.slice(0, limit - 1).concat(input.slice(limit - 1).join(separator));
    }
    return input;
}

#16


0  

My version, universal, supports RegExp and non-RegExp delimiters. Highly optimized. Tests provided. Why: since other RegExp versions are full of bugs and this is not a trivial function.

我的版本,通用,支持RegExp和非RegExp分隔符。高度优化。提供测试。原因:因为其他RegExp版本充满了bug,这不是一个简单的功能。

Usage:

"a b  c   d".split_with_tail(/ +/,3) = ['a','b','c   d']
"a b  c   d".split_with_tail(' ',3) = ['a','b',' c   d']

Code

String.prototype.split_with_tail = function(delimiter,limit)
{
    if( typeof(limit) !== 'number' || limit < 1 ) return this.split(delimiter,limit);

    var parts = this.split(delimiter,limit+1);
    if( parts.length <= limit ) return parts;
    parts.splice(-2,2);

    limit = Math.floor(limit) - 1; // used later as index, speed optimization; limit can be float ..
    if( delimiter instanceof RegExp ) {
        // adds 'g' flag to any regexp:
        delimiter += '';
        var len = delimiter.lastIndexOf('/');
        delimiter = new RegExp(delimiter.slice(1, len), delimiter.slice(len + 1)+'g');

        len = 0;
        while(limit--) len += parts[limit].length + (delimiter.exec(this))[0].length;
    }
    else {
        var len = limit * (''+delimiter).length;
        while(limit--) len += parts[limit].length;
    }

    parts.push(this.substring(len)); // adds tail, finally
    return parts;
}

Tests

function test(str,delimiter,limit,result) {
    if( JSON.stringify(result) !== JSON.stringify(str.split_with_tail(delimiter,limit)) ) {
        console.log(arguments);
        console.log(str.split_with_tail(delimiter,limit));
        throw "lol";
    }
}
test('',/ +/,undefined,['']);
test('',/ +/,3,['']);
test('a',/ +/,0.1,[]);
test('a',/ +/,1,['a']);
test('a a',/ +/,1,['a a']);
test('a a',/ +/,2.1,['a','a']);
test('a a a',/ +/,2.9,['a','a a']);
test('aaaaa aa a',/ +/,1,['aaaaa aa a']);
test('aaaaa aa a',/ +/,2,['aaaaa', 'aa a']);
test('a a',/ +/,2,['a','a']);
test('a',/ +/,3,['a']);
test('a a',/ +/,3,['a','a']);
test('a a  a',/ +/,3,['a','a','a']);
test('a a  a  a',/ +/,3,['a','a','a  a']);
test('a a  a  a',/ +/,4,['a','a','a','a']);
test('a aa  aaa  ',/ +/,4,['a','aa','aaa','']);
test('a a  a  a',/ +/,2,['a','a  a  a']);
test('a a  a  a',/ +/,1,['a a  a  a']);
test('a a  a  a',/ +/,0,[]);
test('a a  a  a',/ +/,undefined,['a','a','a','a']);
test('a a  a  a',/ +/,-1,['a','a','a','a']);

test('a',' ',3,['a']);
test('aaaaa aa a',' ',2,['aaaaa', 'aa a']);
test('aaaaa  aa  a','  ',2,['aaaaa','aa  a']);
test('a a a',' ',3,['a','a','a']);
test('a a a a',' ',3,['a','a','a a']);
test('a a  a a',' ',3,['a','a',' a a']);
test('a a  a a',' ',2,['a','a  a a']);
test('a a  a a',' ',1,['a a  a a']);
test('a a  a a',' ',0,[]);
test('a a  a a',' ',undefined,['a','a','','a','a']);
test('a a  a a',' ',-1,['a','a','','a','a']);
test('1232425',2,3,['1','3','425']);
console.log("good!");

#17


0  

ES2015

const splitAndAppend = (str, delim, count) => {
    const arr = str.split(delim);
    return [...arr.splice(0, count), arr.join(delim)];
}

Complexity O(n).

#1


33  

As per MDN:

根据MDN:

string.split(separator, limit);

Update:

var string = 'Split this, but not this',
    arr = string.split(' '),
    result = arr.slice(0,2);

result.push(arr.slice(2).join(' ')); // ["Split", "this,", "but not this"]

Update version 2 (one slice shorter):

更新版本2(更短一片):

var string = 'Split this, but not this',
    arr = string.split(' '),
    result = arr.splice(0,2);

result.push(arr.join(' ')); // result is ["Split", "this,", "but not this"]

#2


16  

Using Array.slice:

function splitWithTail(str,delim,count){
  var parts = str.split(delim);
  var tail = parts.slice(count).join(delim);
  var result = parts.slice(0,count);
  result.push(tail);
  return result;
}

Results:

splitWithTail(string," ",2)
// => ["Split", "this,", "but not this"]

#3


6  

The JavaScript ".split()" function already accepts a second parameter giving the maximum number of splits to perform. However, it doesn't retain the tail end of your original string; you'd have to glue it back on.

JavaScript“.split()”函数已经接受第二个参数,给出要执行的最大拆分数。但是,它不会保留原始字符串的尾端;你必须重新粘上它。

Another approach would be to iteratively shave off a leading portion of the string with a regex, stopping when you've gotten your limit.

另一种方法是用正则表达式迭代地剪掉字符串的前导部分,当你获得限制时停止。

var str = "hello out there cruel world";
var parts = [];
while (parts.length < 3) { // "3" is just an example
  str = str.replace(/^(\w+)\s*(.*)$/, function(_, word, remainder) {
    parts.push(word);
    return remainder;
  });
}
parts.push(str);

edit — and it just occurs to me that another simple way would be to just use plain ".split()", pluck off the first few parts, and then just ".slice()" and ".join()" the rest.

编辑 - 它只是发生在我身上,另一个简单的方法是使用普通的“.split()”,取出前几个部分,然后只是“.slice()”和“.join()”其余部分。

#4


3  

For this you could use Split(delimiter) and choose a delimiter.

为此,您可以使用Split(分隔符)并选择分隔符。

var testSplit = "Split this, but not this";
var testParts= testSplit.Split(",");

var firstPart = testParts[1];

// firstPart = "Split this"

Not 100% on my syntax I havent used javascript in quite some time. But I know this is how its done...

我的语法不是100%我在很长一段时间没有使用过javascript。但我知道这是怎么做的......

EDIT** Sorry, my mistake. Now I believe I know what your asking and I think the easiest way to do this is using substr. Very easy, no loops required. Just made an example, works perfect

编辑**对不起,我的错误。现在我相信我知道你的要求,我认为最简单的方法就是使用substr。非常简单,无需循环。刚刚做了一个例子,工作完美

// so first, we want to get everything from 0 - the first occurence of the comma.
// next, we want to get everything after the first occurence of the comma.  (if you only define one parameter, substr will take everything after that parameter.

var testString = "Split this, but this part, and this part are one string";
var part1 = testString.substr(0,testString.indexOf(',')); 
var part2 = testString.substr(testString.indexOf(','));

//part1 = "Split this"
//part2= "but this part, and this part are one string"

#5


3  

Combination of split and join with ES6 features does this pretty neat:

分割和连接与ES6功能的结合使这非常简洁:

let [str1, str2, ...str3] = string.split(' ');
str3 = str3.join(' ');

#6


2  

Although you can give split a limit, you won't get back what you've said you want. Unfortunately, you will have to roll your own on this, e.g.:

虽然你可以给予分割限制,但你不会得到你所说的你想要的东西。不幸的是,你必须自己动手,例如:

var string = 'Split this, but not this';
var result = string.split(' ');

if (result.length > 3) {
    result[2] = result.slice(2).join(' ');
    result.length = 3;
}

But even then, you end up modifying the number of spaces in the latter parts of it. So I'd probably just do it the old-fashioned write-your-own-loop way:

但即便如此,您最终还是会修改后面部分的空格数。所以我可能只是采用老式的自编循环方式:

function splitWithLimit(str, delim, limit) {
  var index,
      lastIndex = 0,
      rv = [];

  while (--limit && (index = str.indexOf(delim, lastIndex)) >= 0) {
    rv.push(str.substring(lastIndex, index));
    lastIndex = index + delim.length;
  }
  if (lastIndex < str.length) {
    rv.push(str.substring(lastIndex));
  }
  return rv;
}

Live copy

#7


2  

var result = [string.split(' ',1).toString(), string.split(' ').slice(1).join(' ')];

Results in:

["Split", "this, but not this"]

#8


1  

Hi there i had the same problem wanted to split only several times, couldnt find anything so i just extended the DOM - just a quick and dirty solution but it works :)

嗨,我有同样的问题想分裂几次,无法找到任何东西,所以我只是扩展了DOM - 只是一个快速和肮脏的解决方案,但它的工作:)

String.prototype.split = function(seperator,limit) {
    var value = "";
    var hops  = [];

    // Validate limit
    limit = typeof(limit)==='number'?limit:0;

    // Join back given value
    for ( var i = 0; i < this.length; i++ ) { value += this[i]; }

    // Walkthrough given hops
    for ( var i = 0; i < limit; i++ ) {
        var pos = value.indexOf(seperator);
        if ( pos != -1 ) {
            hops.push(value.slice(0,pos));
            value = value.slice(pos + seperator.length,value.length)

        // Done here break dat
        } else {
            break;
        }
    }
    // Add non processed rest and return
    hops.push(value)
    return hops;
}

In your case would look like that

在你的情况下看起来像那样

>>> "Split this, but not this".split(' ',2)
["Split", "this,", "but not this"]

#9


1  

Improved version of a sane limit implementation with proper RegEx support:

通过适当的RegEx支持改进版本的理智限制实现:

function splitWithTail(value, separator, limit) {
    var pattern, startIndex, m, parts = [];

    if(!limit) {
        return value.split(separator);
    }

    if(separator instanceof RegExp) {
        pattern = new RegExp(separator.source, 'g' + (separator.ignoreCase ? 'i' : '') + (separator.multiline ? 'm' : ''));
    } else {
        pattern = new RegExp(separator.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'), 'g');
    }

    do {
        startIndex = pattern.lastIndex;
        if(m = pattern.exec(value)) {
            parts.push(value.substr(startIndex, m.index - startIndex));
        }
    } while(m && parts.length < limit - 1);
    parts.push(value.substr(pattern.lastIndex));

    return parts;
}

Usage example:

splitWithTail("foo, bar, baz", /,\s+/, 2); // -> ["foo", "bar, baz"]

Built for & tested in Chrome, Firefox, Safari, IE8+.

专为Chrome,Firefox,Safari,IE8 +而设计和测试。

#10


0  

var s='Split this, but not this', a=s.split(','), b=a[0].split(' ');
b.push(a[1]);
alert(b);

alerts ['Split', 'this', 'but not this']

提醒['拆分','这个','但不是这个']

#11


0  

Yet another implementation I just wrote:

我刚写的另一个实现:

export function split(subject, separator, limit=undefined, pad=undefined) {
    if(!limit) {
        return subject.split(separator);
    }
    if(limit < 0) {
        throw new Error(`limit must be non-negative`);
    }
    let result = [];
    let fromIndex = 0;
    for(let i=1; i<limit; ++i) {
        let sepIdx = subject.indexOf(separator, fromIndex);
        if(sepIdx < 0) {
            break;
        }
        let substr = subject.slice(fromIndex, sepIdx);
        result.push(substr);
        fromIndex = sepIdx + separator.length;
    }
    result.push(subject.slice(fromIndex));
    while(result.length < limit) {
        result.push(pad);
    }
    return result;
}

Doesn't use regexes, nor does it over-split and re-join.

不使用正则表达式,也不会过度拆分和重新加入。

This version guarantees exactly limit elements (will pad with undefineds if there aren't enough separators); this makes it safe to do this kind of ES6 stuff:

此版本保证精确限制元素(如果没有足够的分隔符,将填充未定义的);这样做可以安全地做这种ES6的东西:

let [a,b,c] = split('a$b','$',3,null);
// a = 'a', b = 'b', c = null

#12


0  

I like using shift.

我喜欢使用班次。

function splitFirstN(str,n,delim){
    var parts = str.split(delim);
    var r = [];
    for(var i = 0; i < n; i++){
        r.push(parts.shift());
    }
    r.push(parts.join(delim));
    return r;
}

var str = 'Split this, but not this';    
var result = splitFirstN(str,2,' ');

#13


0  

Nothing a one simple regex can't do:

没有一个简单的正则表达式不能做:

const string = 'Split this, but not this';
console.log(string.match(/^(\S+)\s*(\S+)?\s*([\s\S]+)?$/).slice(1));

#14


0  

In my case I was trying to parse git grep stdout. So I had a {filename}:{linenumber}:{context}. I don't like splitting and then joining. We should be able to parse the string one time. You could simply step through each letter and split on the first two colons. A quicker way to do it out of the box is by using the match method and regex.

在我的情况下,我试图解析git grep stdout。所以我有一个{filename}:{linenumber}:{context}。我不喜欢分裂然后加入。我们应该能够解析一次字符串。您可以简单地逐步浏览每个字母并分成前两个冒号。开箱即用的更快捷的方法是使用匹配方法和正则表达式。

Hence,

txt.match(/(.+):(\d+):(.*)/)

Works great

#15


0  

Yet another implementation with limit;

又一个有限制的实施;

// takes string input only
function split(input, separator, limit) {
    input = input.split(separator);
    if (limit) {
        input = input.slice(0, limit - 1).concat(input.slice(limit - 1).join(separator));
    }
    return input;
}

#16


0  

My version, universal, supports RegExp and non-RegExp delimiters. Highly optimized. Tests provided. Why: since other RegExp versions are full of bugs and this is not a trivial function.

我的版本,通用,支持RegExp和非RegExp分隔符。高度优化。提供测试。原因:因为其他RegExp版本充满了bug,这不是一个简单的功能。

Usage:

"a b  c   d".split_with_tail(/ +/,3) = ['a','b','c   d']
"a b  c   d".split_with_tail(' ',3) = ['a','b',' c   d']

Code

String.prototype.split_with_tail = function(delimiter,limit)
{
    if( typeof(limit) !== 'number' || limit < 1 ) return this.split(delimiter,limit);

    var parts = this.split(delimiter,limit+1);
    if( parts.length <= limit ) return parts;
    parts.splice(-2,2);

    limit = Math.floor(limit) - 1; // used later as index, speed optimization; limit can be float ..
    if( delimiter instanceof RegExp ) {
        // adds 'g' flag to any regexp:
        delimiter += '';
        var len = delimiter.lastIndexOf('/');
        delimiter = new RegExp(delimiter.slice(1, len), delimiter.slice(len + 1)+'g');

        len = 0;
        while(limit--) len += parts[limit].length + (delimiter.exec(this))[0].length;
    }
    else {
        var len = limit * (''+delimiter).length;
        while(limit--) len += parts[limit].length;
    }

    parts.push(this.substring(len)); // adds tail, finally
    return parts;
}

Tests

function test(str,delimiter,limit,result) {
    if( JSON.stringify(result) !== JSON.stringify(str.split_with_tail(delimiter,limit)) ) {
        console.log(arguments);
        console.log(str.split_with_tail(delimiter,limit));
        throw "lol";
    }
}
test('',/ +/,undefined,['']);
test('',/ +/,3,['']);
test('a',/ +/,0.1,[]);
test('a',/ +/,1,['a']);
test('a a',/ +/,1,['a a']);
test('a a',/ +/,2.1,['a','a']);
test('a a a',/ +/,2.9,['a','a a']);
test('aaaaa aa a',/ +/,1,['aaaaa aa a']);
test('aaaaa aa a',/ +/,2,['aaaaa', 'aa a']);
test('a a',/ +/,2,['a','a']);
test('a',/ +/,3,['a']);
test('a a',/ +/,3,['a','a']);
test('a a  a',/ +/,3,['a','a','a']);
test('a a  a  a',/ +/,3,['a','a','a  a']);
test('a a  a  a',/ +/,4,['a','a','a','a']);
test('a aa  aaa  ',/ +/,4,['a','aa','aaa','']);
test('a a  a  a',/ +/,2,['a','a  a  a']);
test('a a  a  a',/ +/,1,['a a  a  a']);
test('a a  a  a',/ +/,0,[]);
test('a a  a  a',/ +/,undefined,['a','a','a','a']);
test('a a  a  a',/ +/,-1,['a','a','a','a']);

test('a',' ',3,['a']);
test('aaaaa aa a',' ',2,['aaaaa', 'aa a']);
test('aaaaa  aa  a','  ',2,['aaaaa','aa  a']);
test('a a a',' ',3,['a','a','a']);
test('a a a a',' ',3,['a','a','a a']);
test('a a  a a',' ',3,['a','a',' a a']);
test('a a  a a',' ',2,['a','a  a a']);
test('a a  a a',' ',1,['a a  a a']);
test('a a  a a',' ',0,[]);
test('a a  a a',' ',undefined,['a','a','','a','a']);
test('a a  a a',' ',-1,['a','a','','a','a']);
test('1232425',2,3,['1','3','425']);
console.log("good!");

#17


0  

ES2015

const splitAndAppend = (str, delim, count) => {
    const arr = str.split(delim);
    return [...arr.splice(0, count), arr.join(delim)];
}

Complexity O(n).