Reputation: 15836
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.
Upvotes: 133
Views: 193956
Reputation: 111
I solved my problem using this code, is a somewhat replacement for the missing splice.
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
}
I needed to remove a character before/after a certain word, after you get the position the string is split in two and then recomposed by flexibly removing characters using an offset along pos
Upvotes: 0
Reputation: 53
Louis's spliceSlice method fails when add value is 0 or other falsy values, here is a fix:
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);
}
Upvotes: 0
Reputation: 39
So, whatever adding splice method to a String prototype cant work transparent to spec...
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;
}
Upvotes: 0
Reputation: 8347
There seem to be a lot of confusion which was addressed only in comments by elclanrs and raina77ow, so let me post a clarifying answer.
From "string.splice
" one may expect that it, like the one for arrays:
The problem is, the 3d requirement can not be fulfilled because strings are immutable (related: 1, 2), I've found the most dedicated comment here:
In JavaScript strings are primitive value types and not objects (spec). In fact, as of ES5, they're one of the only 5 value types alongside
null
,undefined
,number
andboolean
. Strings are assigned by value and not by reference and are passed as such. Thus, strings are not just immutable, they are a value. Changing the string"hello"
to be"world"
is like deciding that from now on the number 3 is the number 4... it makes no sense.
So, with that in account, one may expect the "string.splice
" thing to only:
which is what substr
does; or, alternatively,
which is the subject of the next section.
If you care about optimizing, you should probably use the Mike's implementation:
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);
}
Treating the out-of-boundaries index may vary, though. Depending on your needs, you may want:
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;
}
or even
index = index % this.length;
if (index < 0)
index = this.length + index;
If you don't care about performance, you may want to adapt Kumar's suggestion which is more straight-forward:
String.prototype.splice = function(index, count, add) {
var chars = this.split('');
chars.splice(index, count, add);
return chars.join('');
}
The difference in performances increases drastically with the length of the string. jsperf shows, that for strings with the length of 10 the latter solution (splitting & joining) is twice slower than the former solution (using slice), for 100-letter strings it's x5 and for 1000-letter strings it's x50, in Ops/sec it's:
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
note that I've changed the 1st and 2d arguments when moving from 10 letters to 100 letters (still I'm surprised that the test for 100 letters runs faster than that for 10 letters).
Upvotes: 8
Reputation: 151401
It is faster to slice the string twice, like this:
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);
}
than using a split followed by a join (Kumar Harsh's method), like this:
function spliceSplit(str, index, count, add) {
var ar = str.split('');
ar.splice(index, count, add);
return ar.join('');
}
Here's a jsperf that compares the two and a couple other methods. (jsperf has been down for a few months now. Please suggest alternatives in comments.)
Although the code above implements functions that reproduce the general 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.
Upvotes: 114
Reputation: 19609
This is of course not the best way to "splice" a string, I had given this as an example of how the implementation would be, which is flawed and very evident from a split(), splice() and join(). For a far better implementation, see Louis's method.
No, there is no such thing as a String.splice
, but you can try this:
newStr = str.split(''); // or newStr = [...str];
newStr.splice(2,5);
newStr = newStr.join('');
I realise there is no splice
function as in Arrays, so you have to convert the string into an array. Hard luck...
Upvotes: 21
Reputation: 1072
Simply use substr for string
ex.
var str = "Hello world!";
var res = str.substr(1, str.length);
Result = ello world!
Upvotes: 2
Reputation: 3937
The method Louis's 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);
}
Example:
> "Held!".splice(3,0,"lo Worl")
< "Hello World!"
Upvotes: 0
Reputation: 1888
I would like to offer a simpler alternative to both the Kumar/Cody and the Louis methods. On all the tests I ran, it performs as fast as the Louis method (see fiddle tests for benchmarks).
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
See Test Results: https://jsfiddle.net/0quz9q9m/5/
Upvotes: 3
Reputation: 10015
The second function's signature is identical to the Array.prototype.splice
method.
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.
Upvotes: 6