Masukkan string pada indeks tertentu

Jawaban:

257

Anda bisa membuat prototipe milik Anda splice()menjadi String.

Polyfill

if (!String.prototype.splice) {
    /**
     * {JSDoc}
     *
     * The splice() method changes the content of a string by removing a range of
     * characters and/or adding new characters.
     *
     * @this {String}
     * @param {number} start Index at which to start changing the string.
     * @param {number} delCount An integer indicating the number of old chars to remove.
     * @param {string} newSubStr The String that is spliced in.
     * @return {string} A new string with the spliced substring.
     */
    String.prototype.splice = function(start, delCount, newSubStr) {
        return this.slice(0, start) + newSubStr + this.slice(start + Math.abs(delCount));
    };
}

Contoh

String.prototype.splice = function(idx, rem, str) {
    return this.slice(0, idx) + str + this.slice(idx + Math.abs(rem));
};

var result = "foo baz".splice(4, 0, "bar ");

document.body.innerHTML = result; // "foo bar baz"


EDIT: Dimodifikasi untuk memastikan itu remadalah nilai absolut.

pengguna113716
sumber
6
Saya tahu ini dari 2010, tetapi slicesolusi di bawah ini lebih baik dan lebih sederhana. (Splice bersifat merusak, slice tidak, dan lebih baik untuk menghindari memodifikasi "objek yang tidak Anda kenal"). Solusi ini seharusnya sama sekali bukan jawaban yang terlihat pertama, meskipun mungkin masuk akal pada saat itu.
Eirik Birkeland
6
@EirikBirkeland: String tidak dapat diubah. Kode di atas tidak mengubah objek apa pun. Apa pun itu, gagasan Anda untuk tidak mengubah "objek yang tidak Anda kenal " akan menghalangi metode mutasi Array. Anda mengatakan Anda lebih suka melakukan my_array[my_array.length] = itembukan my_array.push(item)?
4
Maaf saya maksudkan "objek yang tidak SENDIRI". Anda benar tentang splicekasus ini; memang string tidak berubah. Untuk alasan ini saya pikir spliceadalah pilihan kata kunci yang buruk sekalipun. Keberatan utama saya adalah menentang perluasan prototipe secara sewenang-wenang, kecuali jika itu polyfill standar.
Eirik Birkeland
1
Ini praktik yang sangat buruk untuk memodifikasi objek bawaan. Seperti yang kita lihat dengan SmooshGate , ini berisiko melanggar kode Anda ketika fungsi baru ditambahkan ke bahasa dan, jika modifikasi tidak bertanggung jawab Anda entah bagaimana masuk ke perpustakaan yang melihat serapan signifikan di web, itu dapat memblokir penggunaan nama metode yang sederhana dan jelas untuk fungsionalitas baru.
Sean
401

Memasukkan pada indeks tertentu (daripada, katakanlah, pada karakter spasi pertama) harus menggunakan slicing / substring string:

var txt2 = txt1.slice(0, 3) + "bar" + txt1.slice(3);
Tim Down
sumber
4
@AlejandroSalamancaMazuelo: substringakan baik-baik saja di sini. Saya lebih suka slicesecara umum karena lebih fleksibel (indeks negatif, misalnya "foo baz".slice(1, -2)). Ini juga sedikit lebih pendek, untuk sedikit yang layak.
Tim Down
8
Apakah ES6 menawarkan alternatif yang lebih baik? Setidaknya bisa menggunakan interpolasi string, seperti`${txt1.slice(0,3)}bar${txt1.slice(3)}`
Jay
1
Ini tidak menggunakan deletefitur seperti yang termasuk dalam di atas; jawaban teratas ...
Tn. Polywhirl
11
@ Mr.Polywhirl: Tidak. Pertanyaannya tidak menyebutkan perlu melakukan itu.
Tim Down
133

Berikut adalah metode yang saya tulis yang berperilaku seperti semua bahasa pemrograman lain:

String.prototype.insert = function(index, string) {
  if (index > 0)
  {
    return this.substring(0, index) + string + this.substring(index, this.length);
  }

  return string + this;
};

//Example of use:
var something = "How you?";
something = something.insert(3, " are");
console.log(something)

Referensi:

Base33
sumber
1
Anda mungkin perlu menambahkan kurung kurawal {}ke blok if-else.
Mr-IDE
3
Tidak, tidak perlu. Tapi elseitu berlebihan.
Bitterblue
72

Buat saja fungsi berikut:

function insert(str, index, value) {
    return str.substr(0, index) + value + str.substr(index);
}

dan kemudian gunakan seperti itu:

alert(insert("foo baz", 4, "bar "));

Output: foo bar baz

Berperilaku tepat, seperti C # (Sharp) String.Insert (int startIndex, nilai string).

CATATAN: insert ini menyisipkan fungsi string value (parameter ketiga) sebelum ditentukan bilangan bulat indeks (parameter kedua) dalam string str (parameter pertama), dan kemudian mengembalikan string baru tanpa mengubah str !


sumber
16

UPDATE 2016: Berikut adalah fungsi prototipe just-for-fun (tapi lebih serius!) Lainnya yang didasarkan pada RegExppendekatan satu-liner (dengan dukungan prepend undefinedatau atau negatif index):

/**
 * Insert `what` to string at position `index`.
 */
String.prototype.insert = function(what, index) {
    return index > 0
        ? this.replace(new RegExp('.{' + index + '}'), '$&' + what)
        : what + this;
};

console.log( 'foo baz'.insert('bar ', 4) );  // "foo bar baz"
console.log( 'foo baz'.insert('bar ')    );  // "bar foo baz"

Solusi just-for-fun sebelumnya (kembali ke 2012) :

var index = 4,
    what  = 'bar ';

'foo baz'.replace(/./g, function(v, i) {
    return i === index - 1 ? v + what : v;
});  // "foo bar baz"
Penglihatan
sumber
1
Ini juga bagus jika Anda perlu menyisipkan teks pada banyak indeks dalam sebuah string. Lihat jawaban saya di bawah ini jika itu masalahnya.
Jake Stoeffler
12

Jika ada yang mencari cara untuk memasukkan teks pada beberapa indeks dalam sebuah string, coba ini:

String.prototype.insertTextAtIndices = function(text) {
    return this.replace(/./g, function(character, index) {
        return text[index] ? text[index] + character : character;
    });
};

Misalnya, Anda dapat menggunakan ini untuk menyisipkan <span>tag pada offset tertentu dalam sebuah string:

var text = {
    6: "<span>",
    11: "</span>"
};

"Hello world!".insertTextAtIndices(text); // returns "Hello <span>world</span>!"
Jake Stoeffler
sumber
1
Saya mencoba metode ini tetapi mengganti '6' dan '11' dengan variabel yang tidak berfungsi - apa yang saya lakukan salah - tolong tolong. Terima kasih sebelumnya :)
Dex Dave
1
6 dan 11 adalah indeks di mana teks akan dimasukkan ke dalam string. 6: "<span>"mengatakan: pada indeks 6, masukkan teks "<span>". Apakah Anda mengatakan bahwa Anda ingin menggunakan nilai variabel integer sebagai indeks penyisipan? Jika itu masalahnya, coba sesuatu sepertivar a=6, text = {}; text[a] = "<span>";
Jake Stoeffler
1
ya saya ingin menggunakan variabel integer sebagai penyisipan, metode Anda bekerja - terima kasih - ini yang saya gunakan var a = 6; var b = 11; text = {}; text [a] = "xx"; text [b] = "yy"; - adakah cara yang lebih baik untuk menulis itu
Dex Dave
11

Ini pada dasarnya melakukan apa yang dilakukan @ Bass33 kecuali saya juga memberikan opsi untuk menggunakan indeks negatif untuk dihitung dari akhir. Jenis seperti metode substr memungkinkan.

// use a negative index to insert relative to the end of the string.

String.prototype.insert = function (index, string) {
  var ind = index < 0 ? this.length + index  :  index;
  return  this.substring(0, ind) + string + this.substring(ind, this.length);
};

Gunakan case: Katakanlah Anda memiliki gambar ukuran penuh menggunakan konvensi penamaan tetapi tidak dapat memperbarui data untuk juga menyediakan url thumbnail.

var url = '/images/myimage.jpg';
var thumb = url.insert(-4, '_thm');

//    result:  '/images/myimage_thm.jpg'
Ryan Ore
sumber
9

Dengan contoh Anda saat ini, Anda dapat mencapai hasilnya dengan baik

var txt2 = txt1.split(' ').join(' bar ')

atau

var txt2 = txt1.replace(' ', ' bar ');

tetapi mengingat Anda dapat membuat asumsi seperti itu, Anda sebaiknya langsung beralih ke contoh Gullen.

Dalam situasi di mana Anda benar-benar tidak dapat membuat asumsi selain berbasis indeks karakter, maka saya benar-benar akan mencari solusi substring.

David Hedlund
sumber
9
my_string          = "hello world";
my_insert          = " dear";
my_insert_location = 5;

my_string = my_string.split('');  
my_string.splice( my_insert_location , 0, my_insert );
my_string = my_string.join('');

https://jsfiddle.net/gaby_de_wilde/wz69nw9k/

pengguna40521
sumber
6

Saya tahu ini adalah utas lama, namun, ini pendekatan yang sangat efektif.

var tn = document.createTextNode("I am just  to help")
t.insertData(10, "trying");

Apa yang hebat tentang ini adalah bahwa ia memaksa konten node. Jadi, jika simpul ini sudah ada di DOM, Anda tidak perlu menggunakan penyeleksi kueri atau memperbarui innerText. Perubahan akan mencerminkan karena hal itu mengikat.

Jika Anda membutuhkan string, cukup akses properti konten teks node.

tn.textContent
#=> "I am just trying to help"
Sebastian Scholl
sumber
6

Kita bisa menggunakan metode substring dan slice.

String.prototype.customSplice = function (index, absIndex, string) {
    return this.slice(0, index) + string+ this.slice(index + Math.abs(absIndex));
};


String.prototype.replaceString = function (index, string) {
    if (index > 0)
        return this.substring(0, index) + string + this.substring(index, this.length);

    return string + this;
};


console.log('Hello Developers'.customSplice(6,0,'Stack ')) // Hello Stack Developers
console.log('Hello Developers'.replaceString(6,'Stack ')) //// Hello Stack Developers

Satu-satunya masalah metode substring adalah tidak akan bekerja dengan indeks negatif. Itu selalu mengambil indeks string dari posisi ke-0.

kamal
sumber
Untuk apa absIndex berdiri?
Enrique Bermúdez
Btw, terima kasih untuk metode kedua. Itu bekerja seperti pesona!
Enrique Bermúdez
5
function insertString(string, insertion, place) {
  return string.replace(string[place] + string[place + 1], string[place] + insertion + string[place + 1])
}

Jadi, bagi Anda, itu akan terjadi insertString("foo baz", "bar", 3);

Jelas, ini akan menjadi cat untuk digunakan karena Anda harus memasok string Anda ke fungsi setiap kali, tetapi saat ini saya tidak tahu bagaimana membuatnya menjadi sesuatu yang lebih mudah seperti a string.replace(insertion, place). Namun, idenya masih berlaku.

Quelklef
sumber
4

Anda dapat menggunakan Ekspresi Reguler dengan pola dinamis .

var text = "something";
var output = "                    ";
var pattern = new RegExp("^\\s{"+text.length+"}");
var output.replace(pattern,text);

output:

"something      "

Ini menggantikan text.lengthkarakter spasi putih di awal string output. The RegExpsarana ^\- mulai dari garis \skarakter ruang putih, berulang {n}kali, dalam hal ini text.length. Gunakan \\untuk \menghindari backslash ketika membangun pola seperti ini dari string.

Tidak bisa dioperasi
sumber
3

solusi lain, potong tali menjadi 2 dan masukkan tali di antaranya.

var str = jQuery('#selector').text();

var strlength = str.length;

strf = str.substr(0 , strlength - 5);
strb = str.substr(strlength - 5 , 5);

jQuery('#selector').html(strf + 'inserted' + strb);
mudshark2005
sumber
3

Anda dapat melakukannya dengan mudah dengan regexp dalam satu baris kode

const str = 'Hello RegExp!';
const index = 6;
const insert = 'Lovely ';
    
//'Hello RegExp!'.replace(/^(.{6})(.)/, `$1Lovely $2`);
const res = str.replace(new RegExp(`^(.{${index}})(.)`), `$1${insert}$2`);
    
console.log(res);

"Halo, Halo, RegExp!"

Madmadi
sumber
2

Menggunakan irisan

Anda bisa menggunakannya slice(0,index) + str + slice(index). Atau Anda dapat membuat metode untuk itu.

String.prototype.insertAt = function(index,str){
  return this.slice(0,index) + str + this.slice(index)
}
console.log("foo bar".insertAt(4,'baz ')) //foo baz bar

Metode sambatan untuk Strings

Anda dapat split()menambahkan string utama dan kemudian gunakan normalsplice()

String.prototype.splice = function(index,del,...newStrs){
  let str = this.split('');
  str.splice(index,del,newStrs.join('') || '');
  return str.join('');
}


 var txt1 = "foo baz"

//inserting single string.
console.log(txt1.splice(4,0,"bar ")); //foo bar baz


//inserting multiple strings
console.log(txt1.splice(4,0,"bar ","bar2 ")); //foo bar bar2 baz


//removing letters
console.log(txt1.splice(1,2)) //f baz


//remving and inseting atm
console.log(txt1.splice(1,2," bar")) //f bar baz

Menerapkan sambungan () pada banyak indeks

Metode ini mengambil array array setiap elemen array mewakili satu splice().

String.prototype.splice = function(index,del,...newStrs){
  let str = this.split('');
  str.splice(index,del,newStrs.join('') || '');
  return str.join('');
}


String.prototype.mulSplice = function(arr){
  str = this
  let dif = 0;
  
  arr.forEach(x => {
    x[2] === x[2] || [];
    x[1] === x[1] || 0;
    str = str.splice(x[0] + dif,x[1],...x[2]);
    dif += x[2].join('').length - x[1];
  })
  return str;
}

let txt = "foo bar baz"

//Replacing the 'foo' and 'bar' with 'something1' ,'another'
console.log(txt.splice(0,3,'something'))
console.log(txt.mulSplice(
[
[0,3,["something1"]],
[4,3,["another"]]
]

))

Maheer Ali
sumber
1

Saya ingin membandingkan metode menggunakan substring dan metode menggunakan slice dari Base33 dan user113716 masing-masing, untuk melakukan itu saya menulis beberapa kode

lihat juga perbandingan kinerja ini , substring, slice

Kode yang saya gunakan menciptakan string besar dan memasukkan string "bar" beberapa kali ke dalam string besar

if (!String.prototype.splice) {
    /**
     * {JSDoc}
     *
     * The splice() method changes the content of a string by removing a range of
     * characters and/or adding new characters.
     *
     * @this {String}
     * @param {number} start Index at which to start changing the string.
     * @param {number} delCount An integer indicating the number of old chars to remove.
     * @param {string} newSubStr The String that is spliced in.
     * @return {string} A new string with the spliced substring.
     */
    String.prototype.splice = function (start, delCount, newSubStr) {
        return this.slice(0, start) + newSubStr + this.slice(start + Math.abs(delCount));
    };
}

String.prototype.splice = function (idx, rem, str) {
    return this.slice(0, idx) + str + this.slice(idx + Math.abs(rem));
};


String.prototype.insert = function (index, string) {
    if (index > 0)
        return this.substring(0, index) + string + this.substring(index, this.length);

    return string + this;
};


function createString(size) {
    var s = ""
    for (var i = 0; i < size; i++) {
        s += "Some String "
    }
    return s
}


function testSubStringPerformance(str, times) {
    for (var i = 0; i < times; i++)
        str.insert(4, "bar ")
}

function testSpliceStringPerformance(str, times) {
    for (var i = 0; i < times; i++)
        str.splice(4, 0, "bar ")
}


function doTests(repeatMax, sSizeMax) {
    n = 1000
    sSize = 1000
    for (var i = 1; i <= repeatMax; i++) {
        var repeatTimes = n * (10 * i)
        for (var j = 1; j <= sSizeMax; j++) {
            var actualStringSize = sSize *  (10 * j)
            var s1 = createString(actualStringSize)
            var s2 = createString(actualStringSize)
            var start = performance.now()
            testSubStringPerformance(s1, repeatTimes)
            var end = performance.now()
            var subStrPerf = end - start

            start = performance.now()
            testSpliceStringPerformance(s2, repeatTimes)
            end = performance.now()
            var splicePerf = end - start

            console.log(
                "string size           =", "Some String ".length * actualStringSize, "\n",
                "repeat count          = ", repeatTimes, "\n",
                "splice performance    = ", splicePerf, "\n",
                "substring performance = ", subStrPerf, "\n",
                "difference = ", splicePerf - subStrPerf  // + = splice is faster, - = subStr is faster
                )

        }
    }
}

doTests(1, 100)

Perbedaan umum dalam kinerja adalah marjinal di terbaik dan kedua metode bekerja dengan baik (bahkan pada untaian panjang ~ ~ 12000000)

Pierre
sumber
0
  1. Instantiate array dari string
  2. Gunakan susunan # array
  3. Stringify lagi menggunakan Array # join

Manfaat dari pendekatan ini ada dua:

  1. Sederhana
  2. Compliant titik kode Unicode

const pair = Array.from('USDGBP')
pair.splice(3, 0, '/')
console.log(pair.join(''))

Ben Aston
sumber