Is there a splice method for strings?

The Javascript splice only works with arrays. Is there similar method for strings? Or should I create my own custom function?

The substr(), and substring() methods will only return the extracted string and not modify the original string. What I want to do is remove some part from my string and apply the change to the original string. Moreover, the method replace() will not work in my case because I want to remove parts starting from an index and ending at some other index, exactly like what I can do with the splice() method. I tried converting my string to an array, but this is not a neat method.

154592 次浏览

Edit

这当然不是“拼接”字符串的最佳方式,我曾经举过这个例子来说明如何实现它,这是有缺陷的,并且从 split ()、 splice ()和 join ()非常明显。有关更好的实现,请参见 路易斯的方法。


不,没有 String.splice这种东西,但是你可以试试这个:

newStr = str.split(''); // or newStr = [...str];
newStr.splice(2,5);
newStr = newStr.join('');

我意识到没有数组中的 splice函数,所以你必须把字符串转换成数组。真倒霉。

将字符串切两次会更快,像这样:

function spliceSlice(str, index, count, add) {
// We cannot pass negative indexes directly to the 2nd slicing operation.
if (index < 0) {
index = str.length + index;
if (index < 0) {
index = 0;
}
}


return str.slice(0, index) + (add || "") + str.slice(index + count);
}

而不是使用拆分后加入(Kumar Harsh 的方法) ,如下所示:

function spliceSplit(str, index, count, add) {
var ar = str.split('');
ar.splice(index, count, add);
return ar.join('');
}

下面的 Jsperf比较了这两种方法和其他一些方法。(jsperf 已经下降了几个月了。请在评论中提出备选方案。)

Although the code above implements functions that reproduce the 将军 functionality of splice, optimizing the code for the case presented by the asker (that is, adding nothing to the modified string) does not change the relative performance of the various methods.

这里有一个不错的小咖喱,它可以提供更好的可读性(恕我直言) :

第二个函数的签名与 Array.prototype.splice方法相同。

function mutate(s) {
return function splice() {
var a = s.split('');
Array.prototype.splice.apply(a, arguments);
return a.join('');
};
}


mutate('101')(1, 1, '1');

I know there's already an accepted answer, but hope this is useful.

我想提供一个简单的方法来替代 Kumar/Cody 方法和 Louis 方法。在我运行的所有测试中,它的执行速度都与 Louis 方法一样快(参见基准测试中的小提琴测试)。

String.prototype.splice = function(startIndex,length,insertString){
return this.substring(0,startIndex) + insertString + this.substring(startIndex + length);
};

You can use it like this:

var creditCardNumber = "5500000000000004";
var cardSuffix = creditCardNumber.splice(0,12,'****');
console.log(cardSuffix);  // output: ****0004

参见测试结果: Https://jsfiddle.net/0quz9q9m/5/

The method 路易斯的 answer, as a String prototype function:

String.prototype.splice = function(index, count, add) {
if (index < 0) {
index = this.length + index;
if (index < 0) {
index = 0;
}
}
return this.slice(0, index) + (add || "") + this.slice(index + count);
}

例如:

 > "Held!".splice(3,0,"lo Worl")
< "Hello World!"

简单地使用字符串 substr

前男友。

var str = "Hello world!";
var res = str.substr(1, str.length);

结果 = 世界好!

似乎有很多困惑,这只是在 Elclanrs 和 Raina77ow 的评论中解决的,所以让我发布一个澄清的答案。

澄清一下

从“ string.splice”中,人们可能会期望它像数组中的那样:

  • 接受最多3个参数: 开始位置、长度和(可选)插入(字符串)
  • 返回剪下来的部分
  • modifies the original string

问题是,3d 需求不能满足,因为字符串是不可变的(相关: 12) ,我找到了最专用的注释 给你:

在 JavaScript 中,字符串是基元值类型和 没有对象(规格)。事实上,在 ES5中,它们是仅有的5种值类型之一,与 nullundefinednumberboolean并列。字符串由 价值没有通过引用分配,并以这种方式传递。因此,字符串不仅是不可变的,它们还是 价值。将字符串 "hello"改为 "world"就像是决定从现在开始数字3就是数字4... 这没有意义。

因此,考虑到这一点,人们可能会认为“ string.splice”只会:

  • 接受最多2个参数: 开始位置、长度(插入没有意义,因为字符串没有更改)
  • 返回剪下来的部分

这正是 substr所做的; 或者,

  • accepts up to 3 arguments: start position, length and (optionally) insertion (string)
  • 返回修改后的字符串(不包含截断部分,并带有插入)

这是下一节的主题。

解决方案

如果您关心优化,您可能应该使用 Mike 的实现:

String.prototype.splice = function(index, count, add) {
if (index < 0) {
index += this.length;
if (index < 0)
index = 0;
}
return this.slice(0, index) + (add || "") + this.slice(index + count);
}

处理越界指数可能会有所不同,根据你的需要,你可能需要:

    if (index < 0) {
index += this.length;
if (index < 0)
index = 0;
}
if (index >= this.length) {
index -= this.length;
if (index >= this.length)
index = this.length - 1;
}

甚至

    index = index % this.length;
if (index < 0)
index = this.length + index;

如果你不在乎表现,你可以采纳库马尔的建议,这个建议更直接:

String.prototype.splice = function(index, count, add) {
var chars = this.split('');
chars.splice(index, count, add);
return chars.join('');
}

表演

性能的差异随着字符串的长度而急剧增加。Jsperf 表演,对于长度为10的字符串,后一种解决方案(分割和连接)比前一种解决方案(使用切片)慢两倍,对于100个字母的字符串,它是 x5,对于1000个字母的字符串,它是 x50,在运算量/秒中,它是:

                      10 letters   100 letters   1000 letters
slice implementation    1.25 M       2.00 M         1.91 M
split implementation    0.63 M       0.22 M         0.04 M

请注意,我已经改变了第一个和第二个参数时,从10个字母到100个字母(仍然我感到惊讶的是,测试100个字母的运行速度比10个字母的运行速度更快)。

因此,无论向 String 原型添加什么样的 splice 方法,都不能对规范透明地工作。

让我们做一些延伸:

String.prototype.splice = function(...a){
for(var r = '', p = 0, i = 1; i < a.length; i+=3)
r+= this.slice(p, p=a[i-1]) + (a[i+1]||'') + this.slice(p+a[i], p=a[i+2]||this.length);
return r;
}
  • 每3个参数组“插入”在拼接风格。
  • 特别是如果有一个以上的3个参数组,结束了每个削减将是下一个开始。
    • “0123456789”。拼接(4,1,“第四”,8,1,“第八”) ;//返回“0123fourth567ightth9”
  • You can drop or zeroing the last arg in each group (that treated as "nothing to insert")
    • ’0123456789’. splice (- 4,2) ;//return’0123459’
  • You can drop all except 1st arg in last group (that treated as "cut all after 1st arg position")
    • ’0123456789’. splice (0,2,null,3,1,null,5,2,’/’,8) ;//return’24/7’;
  • 如果你通过了多个,你必须自己检查位置从左到右的顺序!
  • 如果你不想要你必须不这样使用它:
    • ’0123456789’. splice (4,-3,‘ what?’) ;//返回“0123what? 123456789”

Louis 的 spliceSlice 方法在附加值为0或其他虚假值时失败,这里有一个修复方法:

function spliceSlice(str, index, count, add) {
if (index < 0) {
index = str.length + index;
if (index < 0) {
index = 0;
}
}
const hasAdd = typeof add !== 'undefined';
return str.slice(0, index) + (hasAdd ? add : '') + str.slice(index + count);
}

我用这个代码解决了我的问题,是一个有点替代缺失的拼接。

let str = "I need to remove a character from this";
let pos = str.indexOf("character")


if(pos>-1){
let result = str.slice(0, pos-2) + str.slice(pos, str.length);
console.log(result) //I need to remove character from this
}

我需要在某个单词之前/之后删除一个字符,在您得到位置之后,字符串被分成两部分,然后通过沿 pos使用偏移量灵活地删除字符来重新组合