Bagaimana Anda membalikkan string di tempat (atau di tempat) di JavaScript ketika dilewatkan ke fungsi dengan pernyataan pengembalian, tanpa menggunakan fungsi bawaan ( .reverse()
, .charAt()
dll.)?
javascript
string
reverse
Kobe
sumber
sumber
Jawaban:
Selama Anda berurusan dengan karakter ASCII sederhana, dan Anda senang menggunakan fungsi bawaan, ini akan berfungsi:
Jika Anda membutuhkan solusi yang mendukung UTF-16 atau karakter multi-byte lainnya, perlu diketahui bahwa fungsi ini akan memberikan string unicode yang tidak valid, atau string yang valid yang terlihat lucu. Anda mungkin ingin mempertimbangkan jawaban ini sebagai gantinya .
[... s] menyadari Unicode, hasil edit kecil memberikan: -
sumber
return [...s].reverse().join("");
dapat bekerja.Teknik berikut (atau serupa) biasanya digunakan untuk membalikkan string dalam JavaScript:
Faktanya, semua jawaban yang diposting sejauh ini adalah variasi dari pola ini. Namun, ada beberapa masalah dengan solusi ini. Sebagai contoh:
Jika Anda bertanya-tanya mengapa ini terjadi, baca tentang pengodean karakter internal JavaScript . (TL; DR:
𝌆
adalah simbol astral, dan JavaScript memaparkannya sebagai dua unit kode yang terpisah.)Tapi ada lagi:
String yang baik untuk menguji implementasi string terbalik adalah sebagai berikut :
Mengapa? Karena itu mengandung simbol astral (
𝌆
) (yang diwakili oleh pasangan pengganti dalam JavaScript ) dan tanda menggabungkan (ñ
yang terakhirmañana
sebenarnya terdiri dari dua simbol: U + 006E LATIN KECIL SURAT N dan U + 0303 GABUNG GABUNG).Urutan di mana pasangan pengganti muncul tidak dapat dibalik, selain itu simbol astral tidak akan muncul lagi dalam string 'terbalik'. Itu sebabnya Anda melihat
��
tanda - tanda itu di keluaran untuk contoh sebelumnya.Menggabungkan tanda selalu diterapkan pada simbol sebelumnya, jadi Anda harus memperlakukan kedua simbol utama (U + 006E LATIN SMALL LETTER N) sebagai tanda penggabungan (U + 0303 COMBINING TILDE) secara keseluruhan. Membalikkan urutannya akan menyebabkan tanda gabungan dipasangkan dengan simbol lain dalam string. Itu sebabnya contoh output
ã
bukanñ
.Semoga ini menjelaskan mengapa semua jawaban yang diposting sejauh ini salah .
Untuk menjawab pertanyaan awal Anda - bagaimana [dengan benar] membalikkan string dalam JavaScript -, saya telah menulis perpustakaan JavaScript kecil yang mampu membalikkan string yang sadar-Unicode. Itu tidak memiliki masalah yang baru saja saya sebutkan. Perpustakaan disebut Esrever ; kodenya ada di GitHub, dan berfungsi di hampir semua lingkungan JavaScript. Itu datang dengan utilitas shell / biner, sehingga Anda dapat dengan mudah membalik string dari terminal Anda jika Anda mau.
Sedangkan untuk bagian "di tempat", lihat jawaban lainnya.
sumber
atau
sumber
Analisis terperinci dan sepuluh cara berbeda untuk membalik string dan detail kinerja mereka.
http://eddmann.com/posts/ten-ways-to-reverse-a-string-in-javascript/
Kinerja implementasi ini:
Implementasi berkinerja terbaik per browser
Berikut adalah implementasinya:
Implementasi 1:
Implementasi 2:
Implementasi 3:
Implementasi 4:
Implementasi 5:
Implementasi 6:
Implementasi 7:
Implementasi 8:
Implementasi 9:
Implementasi 10
sumber
Seluruh "membalikkan string di tempat" adalah pertanyaan wawancara programmer C kuno, dan orang-orang yang diwawancarai oleh mereka (untuk balas dendam, mungkin?), Akan bertanya. Sayangnya, ini adalah bagian "Di Tempat" yang tidak lagi berfungsi karena string dalam hampir semua bahasa yang dikelola (JS, C #, dll) menggunakan string yang tidak dapat diubah, sehingga mengalahkan seluruh gagasan untuk memindahkan string tanpa mengalokasikan memori baru.
Sementara solusi di atas memang membalikkan string, mereka tidak melakukannya tanpa mengalokasikan lebih banyak memori, dan dengan demikian tidak memenuhi persyaratan. Anda harus memiliki akses langsung ke string yang dialokasikan, dan dapat memanipulasi lokasi memori aslinya untuk dapat membalikkannya di tempat.
Secara pribadi, saya benar-benar benci pertanyaan wawancara semacam ini, tetapi sayangnya, saya yakin kami akan terus melihatnya selama bertahun-tahun yang akan datang.
sumber
Pertama, gunakan
Array.from()
untuk mengubah string menjadi array, laluArray.prototype.reverse()
membalikkan array, dan kemudianArray.prototype.join()
membuatnya kembali menjadi string.sumber
reverse
logika yang sudah ada sebelumnya .string.split('')
tidak bekerja. Lihat jawaban ini untuk penjelasan lebih lanjut.Array.from('foo 𝌆 bar mañana mañana').reverse().join('') == 'anãnam anañam rab 𝌆 oof'
Array.from('foo 𝌆 bar mañana mañana'.normalize('NFC')).reverse().join('')
akan menjadi"anañam anañam rab 𝌆 oof"
Di ECMAScript 6, Anda dapat membalik string lebih cepat tanpa menggunakan
.split('')
metode split, dengan operator spread seperti:sumber
('')
string.split('')
lebih jelas bagi kebanyakan orang daripada[...string]
..split('')
memiliki masalah dengan karakter dari pesawat tambahan (pasangan pengganti dalam UTF-16), karena terbagi oleh unit kode UTF-16 daripada titik kode . Operator spread danArray.from()
(preferensi saya) tidak.Sepertinya saya terlambat 3 tahun ke pesta ...
Sayangnya Anda tidak bisa seperti yang telah ditunjukkan. Lihat Apakah string JavaScript tidak dapat diubah? Apakah saya memerlukan "pembuat string" dalam JavaScript?
Hal terbaik berikutnya yang dapat Anda lakukan adalah membuat "view" atau "wrapper", yang mengambil string dan menambahkan kembali bagian apa pun dari string API yang Anda gunakan, tetapi pura-pura string tersebut terbalik. Sebagai contoh:
Demo:
Kicker - yang berikut dilakukan di tempat dengan matematika murni, mengunjungi setiap karakter hanya sekali, dan hanya jika perlu:
Ini menghasilkan penghematan yang signifikan jika diterapkan pada string yang sangat besar, jika Anda hanya mengambil sepotong yang relatif kecil.
Apakah ini layak (lebih dari membalik-sebagai-salinan seperti di kebanyakan bahasa pemrograman) sangat tergantung pada kasus penggunaan Anda dan seberapa efisien Anda menerapkan kembali API string. Sebagai contoh jika semua yang Anda inginkan adalah melakukan manipulasi indeks string, atau mengambil
slice
s atausubstr
s kecil, ini akan menghemat ruang dan waktu. Jika Anda berencana untuk mencetak irisan atau substring besar terbalik, penghematan mungkin memang kecil, bahkan lebih buruk daripada melakukan salinan lengkap. String "terbalik" Anda juga tidak akan memiliki tipestring
, meskipun Anda mungkin bisa memalsukan ini dengan membuat prototipe.Implementasi demo di atas membuat objek tipe ReversedString baru. Ini adalah prototipe, dan karenanya cukup efisien, dengan kerja yang hampir minimal dan overhead ruang minimal (definisi prototipe digunakan bersama). Ini adalah implementasi malas yang melibatkan pemotongan yang ditangguhkan. Setiap kali Anda melakukan fungsi seperti
.slice
atau.reversed
, itu akan melakukan indeks matematika. Akhirnya ketika Anda mengekstrak data (dengan menelepon.toString()
atau.charCodeAt(...)
atau sesuatu), akan menerapkan mereka dengan cara yang "pintar", menyentuh data paling mungkin.Catatan: API string di atas adalah contoh, dan mungkin tidak diimplementasikan dengan sempurna. Anda juga dapat menggunakan hanya 1-2 fungsi yang Anda butuhkan.
sumber
Ada banyak cara Anda dapat membalikkan string dalam JavaScript. Saya mencatat tiga cara yang saya sukai.
Pendekatan 1: Menggunakan fungsi terbalik:
Pendekatan 2: Looping melalui karakter:
Pendekatan 3: Menggunakan fungsi pengurangan:
Saya harap ini membantu :)
sumber
Selama wawancara, saya diminta untuk membalik string tanpa menggunakan variabel atau metode asli. Ini adalah implementasi favorit saya:
sumber
slice
? : - /Array.prototype.reverse()
.Ada beberapa cara untuk melakukannya, Anda dapat memeriksa yang berikut,
1. Tradisional untuk loop (incrementing):
2. Tradisional untuk loop (decrementing):
3. Menggunakan for-of loop
4. Menggunakan metode array forEach / pesanan tinggi:
5. standar ES6:
6. Cara terbaru:
7. Anda juga bisa mendapatkan hasilnya menggunakan yang berikut,
sumber
Di ES6, Anda memiliki satu opsi lagi
sumber
Ini adalah cara termudah yang saya pikirkan
sumber
Array.prototype.reverse()
itu akan menjadi cara termudah, karenanya jawaban yang paling populer. Tentu saja, itu membutuhkan pengetahuan sebelumnya tentang JavaScript.ATAU
// Keluaran: 'gnirts elpmas'
sumber
[...str]
.Saya tahu bahwa ini adalah pertanyaan lama yang telah dijawab dengan baik, tetapi untuk hiburan saya sendiri, saya menulis fungsi terbalik berikut dan berpikir saya akan membagikannya jika itu bermanfaat bagi orang lain. Ini menangani kedua pasangan pengganti dan menggabungkan tanda:
Semua alat peraga untuk Mathias, Punycode, dan berbagai referensi lainnya untuk mendidik saya tentang kompleksitas pengkodean karakter dalam JavaScript.
sumber
Anda tidak bisa karena string JS tidak dapat diubah. Solusi singkat di tempat
Tampilkan cuplikan kode
sumber
Jika Anda tidak ingin menggunakan fungsi bawaan apa pun. Coba ini
sumber
Jawaban sebenarnya adalah: Anda tidak dapat membalikkannya di tempat, tetapi Anda dapat membuat string baru yang sebaliknya.
Sama seperti latihan untuk bermain dengan rekursi: kadang-kadang ketika Anda pergi ke sebuah wawancara, pewawancara mungkin bertanya kepada Anda bagaimana melakukan ini menggunakan rekursi, dan saya pikir "jawaban yang disukai" mungkin "Saya lebih suka tidak melakukan ini dalam rekursi karena itu dapat dengan mudah menyebabkan stack overflow "(karena itu
O(n)
bukanO(log n)
. Jika yaO(log n)
, cukup sulit untuk mendapatkan stack overflow - 4 miliar item dapat ditangani oleh level tumpukan 32, karena 2 ** 32 adalah 4294967296. Tetapi jika itu benarO(n)
, maka itu bisa dengan mudah mendapatkan stack overflow.Terkadang pewawancara masih akan bertanya kepada Anda, "sama seperti latihan, mengapa Anda tidak menulisnya menggunakan rekursi?" Dan ini dia:
uji coba:
keluaran:
Untuk mencoba mendapatkan stack overflow, saya beralih
1000
ke10000
di Google Chrome, dan dilaporkan:sumber
String sendiri tidak dapat diubah, tetapi Anda dapat dengan mudah membuat salinan terbalik dengan kode berikut:
sumber
sumber
Fungsi kecil yang menangani penggabungan diakritik dan karakter 2-byte:
Memperbarui
Daftar yang lebih lengkap dari menggabungkan diakritik adalah:
sumber
isCombiningDiacritic
fungsi untuk memasukkan semua rentang 316; merasa bebas untuk memberikan suntingan itu karena Anda tampaknya memiliki data untuk diserahkan.sumber
tanpa mengubah string menjadi array;
menggunakan Array.reverse tanpa mengkonversi karakter ke titik kode;
sumber
var c = array[i-1]; array[i-1] = array[i]; array[i] = c;
tidak perlu menyatukan pasangan kode. Juga, for-loop harus dimulai pada 1.'\ud83c\ud83c\udfa5'.reverse()
- ini akan menghasilkan output yang sama dengan input. Menambahkan++i;
dalamif
pernyataan harus memperbaikinya.'a\u0303bc'.reverse() === 'cba\u0303'
harus mengembalikan true.Saya pikir String.prototype.reverse adalah cara yang baik untuk menyelesaikan masalah ini; kode seperti di bawah ini;
sumber
Menggunakan fungsi Array,
sumber
sumber
Upaya asli saya sendiri ...
http://jsbin.com/bujiwo/19/edit?js,console,output
sumber
Tetap kering dan konyol !!
sumber
OK, cukup sederhana, Anda dapat membuat fungsi dengan loop sederhana untuk melakukan string terbalik untuk Anda tanpa menggunakan
reverse()
,charAt()
dll seperti ini:Misalnya Anda memiliki string ini:
Buat fungsi seperti ini, saya menyebutnya
reverseString
...Dan Anda bisa menyebutnya seperti:
Dan hasilnya adalah:
sumber
Cara terbaik untuk membalikkan string dalam JavaScript
1) Array.reverse:
Anda mungkin berpikir, tunggu dulu saya pikir kami membalikkan string, mengapa Anda menggunakan metode Array.reverse. Menggunakan metode String.split kami mengubah string kami menjadi Array karakter. Kemudian kita membalikkan urutan masing-masing nilai dalam array dan akhirnya kita mengubah Array kembali menjadi sebuah String menggunakan metode Array.join.
2) Pengurangan sementara-loop:
Meski cukup verbose, solusi ini memang memiliki kelebihan dibanding solusi satu. Anda tidak membuat array dan Anda hanya menyatukan string berdasarkan karakter dari string sumber.
Dari perspektif kinerja, yang satu ini mungkin akan menghasilkan hasil terbaik (meskipun belum diuji). Namun untuk string yang sangat panjang, keuntungan kinerja mungkin akan keluar dari jendela.
3) Rekursi
Saya suka betapa sederhana dan jelasnya solusi ini. Anda dapat dengan jelas melihat bahwa metode String.charAt dan String.substr digunakan untuk melewati nilai yang berbeda dengan memanggil dirinya sendiri setiap kali hingga string kosong dimana ternary hanya akan mengembalikan string kosong daripada menggunakan rekursi untuk memanggil dirinya sendiri. . Ini mungkin akan menghasilkan kinerja terbaik kedua setelah solusi kedua.
sumber