Limiting the times that .split() splits, rather than truncating the resulting array

后端 未结 8 1509
耶瑟儿~
耶瑟儿~ 2020-12-11 01:58

Really, pretty much what the title says.

Say you have this string:

var theString = \"a=b=c=d\";

Now, when you run theString

相关标签:
8条回答
  • 2020-12-11 02:36

    I'd use something like this:

    function JavaSplit(string,separator,n) {
        var split = string.split(separator);
        if (split.length <= n)
            return split;
        var out = split.slice(0,n-1);
        out.push(split.slice(n-1).join(separator));
        return out;
    }
    

    What we're doing here is:

    1. Splitting the string entirely
    2. Taking the first n-1 elements, as described.
    3. Re-joining the remaining elements.
    4. Appending them to the array from step 2 and returning.

    One might reasonably think you could chain all of those calls together, but .push() mutates an array rather than returning a new one. It's also a bit easier for you to follow this way.

    0 讨论(0)
  • 2020-12-11 02:41

    If you want the exact equivalent of the Java implementation (no error checking or guard clauses etc):

    function split(str, sep, n) {
        var out = [];
    
        while(n--) out.push(str.slice(sep.lastIndex, sep.exec(str).index));
    
        out.push(str.slice(sep.lastIndex));
        return out;
    }
    
    console.log(split("a=b=c=d", /=/g, 2)); // ['a', 'b', 'c=d']
    

    This has the added benefit of not computing the complete split beforehand, as you mentioned in your question.

    0 讨论(0)
  • 2020-12-11 02:48

    Are you looking for something closer to PHP's explode?

    Here's a method I've devised:

    String.prototype.explode = function(sep, n) {
      var arr = this.split(sep, n)
      if (arr[n-1] != undefined) arr[n-1] += this.substring(arr.join(' ').length);
      return arr;
    }
    

    This method splits the string like normal, determines if we've hit our limit, and uses substring to append the text beyond our last split (we can directly access the offset of the first character beyond the last split by getting the length of a join used on the array with any single character as the separator)

    This method is used just like split:

    str = 'my/uri/needs/to/be/split';
    splitResult = str.split('/', 4);
    explodeResult = str.explode('/', 4);
    console.log(splitResult);
    console.log(explodeResult);
    
    // The following will be written to the console:
    // splitResult:   ["my", "uri", "needs", "to"]
    // explodeResult: ["my", "uri", "needs", "to/be/split"]
    

    And of course, this can be spun as a function too:

    function explode(str, sep, n) {
      var arr = str.split(sep, n)
      if (arr[n-1] != undefined) arr[n-1] += this.substring(arr.join(' ').length);
      return arr;
    }
    
    str = 'my/uri/needs/to/be/split';
    explodeResult = explode(str, '/', 4);
    
    0 讨论(0)
  • 2020-12-11 02:49

    One more possible implementation:

    function split(s, separator, limit) {
      // split the initial string using limit
      var arr = s.split(separator, limit);
      // get the rest of the string...
      var left = s.substring(arr.join(separator).length + separator.length);
      // and append it to the array
      arr.push(left);
      return arr;
    }
    

    Fiddle is here.

    0 讨论(0)
  • 2020-12-11 02:49

    The answer from Asad is excellent as it allows for variable length RegExp separators (e.g. /\s+/g, splitting along any length of whitespace, including newlines). However, there are a couple issues with it.

    1. If the separator does not use the global flag, it will break.
    2. The exec can return null and cause it to break. This can happen if the separator does not appear in the input string.

    The following addresses these two issues:

    export function split(input, separator, limit) {
      if (!separator.global) {
        throw new Error("The split function requires the separator to be global.");
      }
    
      const output = [];
    
      while (limit--) {
        const lastIndex = separator.lastIndex;
        const search = separator.exec(input);
        if (search) {
          output.push(input.slice(lastIndex, search.index));
        }
      }
    
      output.push(input.slice(separator.lastIndex));
    
      return output;
    }
    
    0 讨论(0)
  • 2020-12-11 02:50

    If you want to do that in less lines and avoiding loops:

    const theString = "some=string=with=separators";
    const limit = 2;
    const parts = theString.split('=', limit);
    parts.push(theString.slice(parts.join('').length + limit));
    
    0 讨论(0)
提交回复
热议问题