Есть ли метод сращивания для строк?
Javascript splice
работает только с массивами. Есть ли аналогичный метод для строк? Или я должен создать свою собственную пользовательскую функцию?
Методы substr()
и substring()
возвращают только извлеченную строку и не изменяют исходную строку. Я хочу, чтобы удалить часть из моей строки и применить изменение к исходной строке. Более того, метод replace()
не будет работать в моем случае, потому что я хочу удалить части, начиная с индекса и заканчивая каким-либо другим индексом, точно так же, как то, что я могу сделать с помощью метода splice()
. Я попытался преобразовать свою строку в массив, но это не аккуратный метод.
Ответы
Ответ 1
Это быстрее нарезать строку дважды, как это:
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);
}
чем использование разбиения с последующим соединением (метод Кумара Харша), например:
function spliceSplit(str, index, count, add) {
var ar = str.split('');
ar.splice(index, count, add);
return ar.join('');
}
Здесь jsperf, который сравнивает два и пару других методов. (jsperf не работает уже несколько месяцев. Пожалуйста, предложите альтернативы в комментариях.)
Хотя приведенный выше код реализует функции, которые воспроизводят общие функциональные возможности splice
, оптимизация кода для случая, представленного запрашивающим (то есть, ничего не добавляя к измененной строке), не меняет относительную производительность различных методов.
Ответ 2
Изменить
Это, конечно, не лучший способ "сплайсинга" строки, я дал это как пример того, как будет реализована реализация, которая является ошибочной и очень очевидной из split(), splice() и join()). Для более эффективной реализации см. Метод Луи.
Нет, нет такой вещи, как String.splice
, но вы можете попробовать следующее:
newStr = str.split(''); // or newStr = [...str];
newStr.splice(2,5);
newStr = newStr.join('');
Я понимаю, что нет функции splice
, как в массивах, поэтому вам нужно преобразовать строку в массив. Удачи...
Ответ 3
Здесь хороший маленький Curry, который обеспечивает лучшую читаемость (IMHO):
Вторая сигнатура функции идентична методу 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');
Я знаю, что уже есть принятый ответ, но надеюсь, что это полезно.
Ответ 4
Ответ Луи в качестве функции прототипа 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
Я хотел бы предложить более простую альтернативу методам Кумара/Коди и Луи. Во всех тестах, которые я запускал, он работает так же быстро, как метод Луи (см. Тесты на скрипку для тестов).
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/
Ответ 6
Просто используйте substr для строки
ех.
var str = "Hello world!";
var res = str.substr(1, str.length);
Результат = мир ello!
Ответ 7
Итак, что бы ни добавлял метод сращивания к прототипу 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 аргумента группа "вставляет" в стиле сплайсинга.
- Специально, если есть более одной группы из 3 аргументов, конец каждого выреза будет началом следующего.
- '0123456789'.splice(4,1,' четвёртую", 8,1 'восьмого'); //вернуть '0123fourth567eighth9'
- Вы можете удалить или обнулить последний аргумент в каждой группе (который рассматривается как "нечего вставлять")
- "0123456789'.splice(-4, 2); //вернуть '0123459'
- Вы можете отбросить все, кроме 1-го аргумента, в последней группе (которая рассматривается как "вырезать все после 1-го положения арга")
- '0123456789'.splice(0,2, NULL, 3,1, NULL, 5,2,'/", 8); //возвращаем '24/7 '
- если вы передаете несколько, вы ДОЛЖНЫ сами проверять сортировку позиций слева направо!
- И если вы не хотите, вы НЕ ДОЛЖНЫ использовать это так:
- '0123456789'.splice(4, -3,' что "?); // возвращаем "0123 что? 123456789"
Ответ 8
Кажется, здесь много путаницы, о которой говорили только в комментариях elclanrs и raina77ow, поэтому позвольте мне опубликовать уточняющий ответ.
осветление
От " string.splice
" можно ожидать, что он, как и для массивов:
- принимает до 3 аргументов: начальная позиция, длина и (необязательно) вставка (строка)
- возвращает вырезанную часть
- изменяет исходную строку
Проблема в том, что 3D-требование не может быть выполнено, потому что строки неизменны (связанные: 1, 2), я нашел самый специальный комментарий здесь:
В JavaScript строки являются примитивными типами значений, а не объектами (spec). На самом деле, начиная с ES5, они являются одним из 5 типов значений, кроме null
, undefined
, number
и boolean
. Строки присваиваются по значению, а не по ссылке и передаются как таковые. Таким образом, строки не просто неизменны, они являются ценностью. Изменение строки "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;
Если вы не заботитесь о производительности, вы можете изменить предложение Кумара, что более просто:
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
обратите внимание, что я изменил 1-й и 2-й аргументы при переходе с 10 букв на 100 букв (тем не менее я удивлен, что тест для 100 букв выполняется быстрее, чем тест для 10 букв).