Javascript 限制.split()拆分的时间,而不是截断生成的数组

Javascript 限制.split()拆分的时间,而不是截断生成的数组,javascript,split,query-string,Javascript,Split,Query String,真的,和标题差不多 假设您有以下字符串: var theString = "a=b=c=d"; 现在,当您运行字符串.split(“=”时,结果是[“a”、“b”、“c”、“d”]。当然,当您运行字符串.split(“=”,2)时,您会得到[“a”,“b”],这在阅读后对我来说是有意义的 但是,我要寻找的行为更像Java的String#split():它不是正常构建数组,然后返回前n个元素,而是构建一个包含前n-1个匹配项的数组,然后添加所有剩余字符作为数组的最后一个元素。有关更好的描述,请参

真的,和标题差不多

假设您有以下字符串:

var theString = "a=b=c=d";
现在,当您运行字符串.split(“=”时,结果是
[“a”、“b”、“c”、“d”]
。当然,当您运行
字符串.split(“=”,2)
时,您会得到
[“a”,“b”]
,这在阅读后对我来说是有意义的

但是,我要寻找的行为更像Java的
String#split()
:它不是正常构建数组,然后返回前n个元素,而是构建一个包含前n-1个匹配项的数组,然后添加所有剩余字符作为数组的最后一个元素。有关更好的描述,请参阅

如何在Javascript中获得这种效果

我正在寻找与Java实现类似的最佳性能的答案,尽管它的实际工作方式可能有所不同


我会发布我的尝试,但我根本不知道如何开始写这篇文章。

我会使用以下内容:

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;
}
函数JavaSplit(字符串,分隔符,n){ var split=string.split(分隔符);
如果(split.length还有一种可能的实现方式:

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是。

如果您想要与Java实现完全等效(无错误检查或保护子句等):


正如您在问题中提到的那样,这还有一个额外的好处,即不必事先计算完整的拆分。

您是否在寻找更接近PHP的拆分

我想出了一个方法:

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;
}
此方法像普通方法一样拆分字符串,确定是否已达到限制,并使用
子字符串
将文本追加到上次拆分之后(我们可以通过获取数组上使用的
连接的
长度
,直接访问第一个字符在最后一次拆分之后的偏移量,该数组使用任何单个字符作为分隔符)

此方法的使用方式与拆分类似:

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"]
当然,这也可以作为一个函数进行旋转:

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);

如果要在较少的行中执行此操作并避免循环:

const theString = "some=string=with=separators";
const limit = 2;
const parts = theString.split('=', limit);
parts.push(theString.slice(parts.join('').length + limit));
const theString=“a=b=c=d”;
常量[first,…rest]=字符串拆分(“=”);
const second=rest.join(“=”)

console.log(第一,第二)
这是我的实现:

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;
}
String.prototype.splitrements=函数(delim,count){
如果(delim的类型!=='string'){
返回这个.split();
}
如果(计数类型!=='number'){
返回此。拆分(delim);
}
如果(计数<2){
返回此。拆分(delim);
}
计数--;
const parts=此.split(delim,count);
常量余数=此.slice(parts.join(“”).length+count);
如果(余数.长度>0){
零件。推送(剩余);
}
返回部件;
}
log(“dasd-asds-asds-asdasd-asdasdas.splitrements(“,4));
console.log(“你好”。splitrements(“-”,2));
来自Asad的代码非常优秀,因为它允许使用可变长度的RegExp分隔符(例如,
/\s+/g
,沿任意长度的空格拆分,包括换行符)。但是,它存在一些问题

  • 如果分隔符不使用全局标志,它将中断
  • exec
    可以返回
    null
    并导致其中断。如果输入字符串中没有出现分隔符,则可能发生这种情况
  • 如果限制大于分隔点,则最终将在字符串上循环,并可能产生意外结果
  • 限制是必需的,因此无法轻松找到最大拆分
  • 以下内容在同样有效的情况下解决了这些问题:

    /**
    *使用RegExp分隔符拆分字符串的次数(可选)有限。
    *@param{string}输入
    *@param{RegExp}分隔符
    *@param{number}[limit]-如果未包含,则拆分最大次数
    *@返回{string[]}
    */
    功能拆分(输入、分隔符、限制){
    //确保分隔符是全局的
    separator=newregexp(分隔符'g');
    //允许排除限制参数
    极限=极限???-1;
    常量输出=[];
    设finalIndex=0;
    while(限制--){
    const lastIndex=separator.lastIndex;
    const search=separator.exec(输入);
    如果(搜索===null){
    打破
    }
    finalIndex=separator.lastIndex;
    push(input.slice(lastIndex,search.index));
    }
    output.push(input.slice(finalIndex));
    返回输出;
    }
    
    split(“foo-bar-baz-qux”,/\s+/,3)
    //[“foo”、“bar”、“baz”、“quox”]
    拆分(“foo-bar-baz-qux”,/\s+/,2)
    //[“foo”、“bar”、“baz-quox”]
    拆分(“foo-bar-baz-qux”,/\s+/,1)
    //[“foo”,“bar baz qux”]
    拆分(“foo-bar-baz-qux”,/\s+/,0)
    //[“foo bar baz quux”]
    //比可能的拆分更高的限制
    拆分(“foo-bar-baz-qux”,/\s+/,4)
    //[“foo”、“bar”、“baz”、“quox”]
    //不存在的分裂
    拆分(“foo-bar-baz-qux”,/p/,2)
    //[“foo bar baz quux”]
    //不提供限制将查找最大拆分
    拆分(“foo-bar-baz-qux”,/\s+/)
    //[“foo”、“bar”、“baz”、“quox”]
    
    注:

    在生产代码中,建议不要变异函数参数。
    分隔符
    限制
    都在变异。如果需要,可以选择在函数顶部创建新变量以避免这种情况。我选择不这样做是为了使示例代码简短。这不是生产代码

    < P>我没有包含任何防御代码来检查函数参数类型。这将是一个很好的事情来考虑生产代码,或考虑TypeScript;)< /P>
    最初,如果提供的分隔符未设置全局标志,我抛出了一个
    错误
    。请参阅下面的评论,了解为什么可能需要为用户添加全局标志而不是抛出。感谢您的建议@Stephen p。

    嗨,可能您需要在执行sli之前检查分割结果长度是否大于nce,否则只返回分割结果。我喜欢这个简单,但我接受另一个,因为(据我所知,没有基准测试)它更有效。是的,我很好奇