Javascriptsplice
仅适用于数组。字符串有类似的方法吗?还是应该创建自己的自定义函数?
该substr()
和substring()
方法将只返回提取的字符串,而不是修改原始字符串。我想要做的是从我的字符串中删除一些部分并将更改应用于原始字符串。此外,该方法replace()
在我的情况下不起作用,因为我想删除从索引开始并以其他索引结束的部分,就像我可以用该splice()
方法做的那样。我尝试将字符串转换为数组,但这不是一个巧妙的方法。
Javascriptsplice
仅适用于数组。字符串有类似的方法吗?还是应该创建自己的自定义函数?
该substr()
和substring()
方法将只返回提取的字符串,而不是修改原始字符串。我想要做的是从我的字符串中删除一些部分并将更改应用于原始字符串。此外,该方法replace()
在我的情况下不起作用,因为我想删除从索引开始并以其他索引结束的部分,就像我可以用该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 已经关闭几个月了。请在评论中提出替代方案。)
尽管上面的代码实现了重现 的一般功能的函数splice
,但是针对提问者呈现的情况优化代码(即,不向修改后的字符串添加任何内容)并不会改变各种方法的相对性能。
这当然不是“拼接”字符串的最佳方式,我已经给出了它作为实现方式的示例,这是有缺陷的,并且从 split()、splice() 和 join() 中非常明显。要获得更好的实现,请参阅Louis 的方法。
不,没有像 a 这样的东西String.splice
,但你可以试试这个:
newStr = str.split(''); // or newStr = [...str];
newStr.splice(2,5);
newStr = newStr.join('');
我意识到没有splice
像数组那样的函数,所以你必须将字符串转换为数组。运气不好...
第二个函数的签名与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');
我知道已经有一个可以接受的答案,但希望这是有用的。
似乎有很多困惑只在 elclanrs 和 Raina77ow 的评论中得到解决,所以让我发布一个澄清的答案。
从 " string.splice
" 可能会期望它,就像数组一样:
问题是,无法满足 3d 要求,因为字符串是不可变的(相关:1 , 2),我在这里找到了最专业的评论:
在 JavaScript 中,字符串是原始值类型而不是对象 ( spec )。事实上,作为ES5的,他们是只有5值类型之一旁边
null
,undefined
,number
和boolean
。字符串按值而不是按引用分配,并按原样传递。因此,字符串不仅是不可变的,它们还是一个值。更改字符串"hello"
是"world"
就像决定,从现在起的3号是多少4 ...这没有任何意义。
因此,考虑到这一点,人们可能会期望“ string.splice
”事物仅:
这是什么substr
;或者,或者,
这是下一节的主题。
如果您关心优化,您可能应该使用 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;
如果您不关心性能,您可能需要调整 Kumar 的更直接的建议:
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,在 Ops/秒它是:
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 个字母时,我更改了 1st 和 2d 参数(我仍然惊讶于 100 个字母的测试运行速度比 10 个字母的测试运行得更快)。
我想为 Kumar/Cody 和 Louis 方法提供一个更简单的替代方案。在我运行的所有测试中,它的执行速度与 Louis 方法一样快(请参阅基准测试的小提琴测试)。
String.prototype.splice = function(startIndex,length,insertString){
return this.substring(0,startIndex) + insertString + this.substring(startIndex + length);
};
你可以这样使用它:
var creditCardNumber = "5500000000000004";
var cardSuffix = creditCardNumber.splice(0,12,'****');
console.log(cardSuffix); // output: ****0004
查看测试结果:https : //jsfiddle.net/0quz9q9m/5/