Wydaje się, że jest wiele nieporozumień, które zostały rozwiązane tylko w komentarzach elclanrs i raina77ow, więc pozwólcie, że opublikuję wyjaśniającą odpowiedź.
Wyjaśnienie
Z "string.splice ” można by się tego spodziewać, podobnie jak w przypadku tablic:
- przyjmuje do 3 argumentów: pozycja początkowa, długość i (opcjonalnie) wstawienie (ciąg)
- zwraca wyciętą część
- modyfikuje oryginalny ciąg
Problem w tym, że wymaganie 3d nie może zostać spełnione, ponieważ ciągi znaków są niezmienne (powiązane: 1 , 2 ), najbardziej dedykowany komentarz znalazłem tutaj :
W JavaScript łańcuchy są prymitywnymi typami wartości, a nie obiektami ( specyfikacjami ). W rzeczywistości, jak z ES5, są jedną z zaledwie 5 typów wartości obok null, undefined, numberi boolean. Ciągi są przypisywane przez wartość, a nie przez odwołanie i jako takie są przekazywane. W ten sposób ciągi znaków są nie tylko niezmienne, są one wartością . Zmiana ciąg "hello"być "world"jakby uznając, że od teraz numer 3 to numer 4 ... to nie ma sensu.
Tak więc, biorąc to pod uwagę, można oczekiwać, że „ string.splice” tylko:
- przyjmuje do 2 argumentów: pozycja początkowa, długość (wstawianie nie ma sensu, ponieważ ciąg nie jest zmieniany)
- zwraca wyciętą część
co jest tym, co substrrobi; lub alternatywnie
- przyjmuje do 3 argumentów: pozycja początkowa, długość i (opcjonalnie) wstawienie (ciąg)
- zwraca zmodyfikowany ciąg (bez wyciętej części iz wstawieniem)
co jest tematem następnej sekcji.
Rozwiązania
Jeśli zależy Ci na optymalizacji, prawdopodobnie powinieneś skorzystać z implementacji Mike'a:
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);
}
Traktowanie wskaźnika poza granicami może się jednak różnić. W zależności od potrzeb możesz chcieć:
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;
}
lub nawet
index = index % this.length;
if (index < 0)
index = this.length + index;
Jeśli nie zależy Ci na wydajności, możesz dostosować sugestię Kumara, która jest prostsza:
String.prototype.splice = function(index, count, add) {
var chars = this.split('');
chars.splice(index, count, add);
return chars.join('');
}
Występ
Różnica w wykonaniu drastycznie rośnie wraz z długością struny. jsperf pokazuje , że dla łańcuchów o długości 10 to drugie rozwiązanie (dzielenie i łączenie) jest dwukrotnie wolniejsze niż poprzednie rozwiązanie (z użyciem plasterka), dla 100-literowych łańcuchów to x5, a dla 1000-literowych to x50, w Ops / s to:
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
zwróć uwagę, że zmieniłem argumenty 1. i 2. przy przechodzeniu z 10 liter na 100 liter (nadal jestem zaskoczony, że test na 100 liter działa szybciej niż na 10 liter).
str.splitmoże to być funkcja, której szukasz: google.com/#q=javascript+string+split