字符串是否有拼接方法?

时间:2013-12-28 18:00:33

标签: javascript

Javascript splice仅适用于数组。字符串有类似的方法吗?或者我应该创建自己的自定义函数吗?

substr()substring()方法只会返回提取的字符串,而不会修改原始字符串。我想要做的是从我的字符串中删除一些部分并将更改应用于原始字符串。此外,方法replace()在我的情况下不起作用,因为我想从索引开始删除部分并以其他索引结束,就像我可以用splice()方法做的那样。我尝试将我的字符串转换为数组,但这不是一个简洁的方法。

10 个答案:

答案 0 :(得分:76)

将字符串切片两次更快,如下所示:

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常规功能的函数,但优化了提问者提供的案例的代码(即,不对修改后的字符串添加任何内容)不改变各种方法的相对表现。

答案 1 :(得分:14)

修改

这当然不是“拼接”字符串的最佳方式,我已经将此作为实现方式的一个示例,这是有缺陷的,并且从split(),splice()和join(非常明显) )。有关更好的实现,请参阅Louis's方法。


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

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

我意识到在数组中没有splice函数,所以你必须将字符串转换为数组。好运......

答案 2 :(得分:5)

这是一个很好的小咖喱,它提供了更好的可读性(恕我直言):

第二个函数的签名与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');

我知道已经接受了答案,但希望这很有用。

答案 3 :(得分:2)

我想为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/

答案 4 :(得分:2)

方法Louis's回答,作为String原型函数:

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!"

答案 5 :(得分:2)

只需使用 substr 作为字符串

离。

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

结果= ello world!

答案 6 :(得分:1)

似乎有很多困惑,只有Elclanrs和Raina77ow的评论才解决,所以让我发表一个明确的答案。

澄清

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

  • 最多接受3个参数:开始位置,长度和(可选)插入(字符串)
  • 退回切除的部分
  • 修改原始字符串

问题是,因为字符串是不可变的(相关:12),所以无法满足3d要求,我发现了最专门的评论here

  

在JavaScript字符串中,原始值类型是 not 对象(spec)。实际上,从ES5开始,它们是nullundefinednumberboolean之外仅有的5种值类型之一。字符串由 value not 通过引用分配,并按原样传递。因此,字符串不仅是不可变的,而且是一个 value 。将字符串"hello"更改为"world"就像从现在开始确定数字3是数字4 ...毫无意义。

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

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

substr的作用;或者,或者,

  • 最多接受3个参数:开始位置,长度和(可选)插入(字符串)
  • 返回修改后的字符串(不带剪切部分,并插入)

这是下一节的主题。

解决方案

如果您关心优化,则可能应该使用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 shows,对于长度为10的字符串,后一种解决方案(拆分和连接)比前一种解决方案(使用切片)慢两倍,对于100个字母的字符串为x5,对于1000个字母的字符串为x50 ,以Ops / sec为单位:

                      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个字母的测试要快)。

答案 7 :(得分:1)

因此,无论如何在String原型中添加拼接方法都无法对规范透明...

让我们做一些扩展:

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个args组以拼接样式“插入”。
  • 特别是如果有3个以上的参数组,则每个切割的结束将是下一个切割的开始。
    • '0123456789'.splice(4,1,'fourth',8,1,'eighth'); //返回“ 0123fourth567eighth9”
  • 您可以删除或归零每个组中的最后一个arg(被视为“无可插入”)
    • '0123456789'.splice(-4,2); //返回“ 0123459”
  • 您可以删除除最后一个组中的第一个arg以外的所有内容(将其视为“在第一个arg位置之后全部剪切”)
    • '0123456789'.splice(0,2,null,3,1,null,5,2,'/',8); //返回“ 24/7”
  • 如果您多次通过,则必须自己检查从左到右顺序的位置!
  • 如果您不想要,请不要这样使用它:
    • '0123456789'.splice(4,-3,'what?''); //返回“ 0123what?123456789”

答案 8 :(得分:0)

Louis's spliceSlice方法在add值为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);
}

答案 9 :(得分:0)

我使用这段代码解决了我的问题,在某种程度上替代了缺失的接头。

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上的偏移量灵活地删除字符来重新组成