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,否则只返回分割结果。我喜欢这个简单,但我接受另一个,因为(据我所知,没有基准测试)它更有效。是的,我很好奇