Подтвердить что ты не робот

Есть ли метод сращивания для строк?

Javascript splice работает только с массивами. Есть ли аналогичный метод для строк? Или я должен создать свою собственную пользовательскую функцию?

Методы substr() и substring() возвращают только извлеченную строку и не изменяют исходную строку. Я хочу, чтобы удалить часть из моей строки и применить изменение к исходной строке. Более того, метод replace() не будет работать в моем случае, потому что я хочу удалить части, начиная с индекса и заканчивая каким-либо другим индексом, точно так же, как то, что я могу сделать с помощью метода splice(). Я попытался преобразовать свою строку в массив, но это не аккуратный метод.

4b9b3361

Ответ 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 букв).