Bagaimana cara memeriksa apakah suatu string “Mulai dengan” string lain?

Jawaban:

1773

Anda dapat menggunakan String.prototype.startsWith()metode ECMAScript 6 , tetapi belum didukung di semua browser . Anda akan ingin menggunakan shim / polyfill untuk menambahkannya di browser yang tidak mendukungnya. Membuat implementasi yang sesuai dengan semua detail yang tercantum dalam spesifikasi agak rumit. Jika Anda menginginkan shim yang setia, gunakan:

Setelah Anda memangkas metode (atau jika Anda hanya mendukung browser dan mesin JavaScript yang sudah memilikinya), Anda dapat menggunakannya seperti ini:

"Hello World!".startsWith("He"); // true

var haystack = "Hello world";
var prefix = 'orl';
haystack.startsWith(prefix); // false
CMS
sumber
@ gtournie mengapa akan dimulai dengan menjadi salah satu metode terburuk untuk menguji jika sebuah string dimulai dengan sebuah string? (lihat komentar Anda di sini: stackoverflow.com/questions/646628/… ) Anda lebih antusias membandingkan karakter per karakter. saya harap kompiler cukup pintar TIDAK untuk menghasilkan string untuk setiap string [indeks] karena, jika Anda hanya menulis ini: karakter = string [0] itu AKAN mengalokasikan objek, jauh KURANG efisien daripada menggunakan beginWith (beginWith tidak akan mengalokasikan memori apa pun) )
Martijn Scheffer
@ MartijnScheffer: Jawabannya telah diedit beberapa kali sejak saya menjawab dan sekarang sangat berbeda (saya menghapus komentar saya;). Saya setuju bahwa metode beginWith ECMAScript 6 adalah cara terbaik untuk melakukannya.
gtournie
6
@ GrahamLaight, ketika Anda mengatakan didukung oleh 'IE', mungkin maksud Anda dengan Edge. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Marcus
@Marcus, maaf jika saya salah - informasi saya berasal dari: w3schools.com/jsref/jsref_startswith.asp
Graham Laight
PERINGATAN! Tes jsperf ini tidak berfungsi di browser yang bagus dalam kompilasi JIT. Peramban seperti Firefox dan Chrome terkadang mengenalinya ketika hasil operasi dibuang, dan karenanya tidak melakukan operasi . Selain itu, mesin javascript modern menggunakan prediksi cabang , sehingga string tes harus berbeda di setiap iterasi.
Aloso
1283

Alternatif lain dengan .lastIndexOf:

haystack.lastIndexOf(needle, 0) === 0

Hal ini terlihat mundur melalui haystackuntuk terjadinya needlemulai dari indeks 0dari haystack. Dengan kata lain, itu hanya memeriksa jika haystackdimulai dengan needle.

Pada prinsipnya, ini harus memiliki keunggulan kinerja dibandingkan beberapa pendekatan lain:

  • Itu tidak mencari keseluruhan haystack.
  • Itu tidak membuat string sementara baru dan kemudian segera membuangnya.
Mark Byers
sumber
1
Tidak yakin kasing mana yang diambil @ rfcoder89 - jsfiddle.net/jkzjw3w2/1
Gulfaraz Rahman
5
@ rfcoder89 Perhatikan parameter kedua lastIndexOf: "aba".lastIndexOf ("a")adalah 2 seperti yang Anda tunjukkan, tetapi "aba".lastIndexOf ("a", 0)0, yang benar
maxpolk
1
Terima kasih banyak. String.startsWith tidak bekerja di Android lollipop WebView, tetapi cuplikanIndexOf terakhir ini tidak !!!
Herman
dengan lastIndexOf string dicari dari akhir hingga awal sehingga mencari seluruh string: jadi inefisiensinya tumbuh untuk string yang sangat panjang untuk dicari.
willy wonka
8
@willywonka Tidak, itu bukan jika Anda memiliki 0 startIndex, itu dicari dari 0 pos dan itu satu-satunya cek. Seluruh string hanya dicari jika dariIndex> = str.length.
Greene
588
data.substring(0, input.length) === input
cobbal
sumber
3
@ ANeves Saya curiga ini sangat tergantung pada browser dan data yang digunakan. Lihat jawaban Ben Weaver untuk pengukuran aktual. Di browser yang saya gunakan saat ini (Chrome 12.0.742 pada Windows) mensubstruksikan kemenangan untuk sukses dan menyiapkan kemenangan regex untuk kegagalan.
cobbal
4
@cobbal Mungkin. Tapi .lastIndexOf(input, 0)bandingkan karakter N pertama, sedangkan .substring(0, input.length) === inputjumlah N, substring data ke panjang N, dan kemudian bandingkan karakter N tersebut. Kecuali ada optimasi kode, versi kedua ini tidak bisa lebih cepat dari yang lain. Tapi jangan salah paham, saya tidak akan pernah menemukan sendiri sesuatu yang lebih baik dari yang Anda sarankan. :)
ANeves
2
@ ANeves Tapi. LastIndexOf pada string panjang yang akan mengembalikan false akan beralih ke seluruh string (O (N)), sedangkan kasus .substring beralih pada string yang mungkin jauh lebih kecil. Jika Anda mengharapkan keberhasilan mayoritas atau hanya input kecil, .lastIndexOf kemungkinan lebih cepat - jika tidak. Substring mungkin lebih cepat. .substring juga beresiko pengecualian jika input lebih panjang dari string yang diperiksa.
Chris Moschini
14
@ ChrisMoschini, jangan lupa bahwa solusi Mark Byers 'telah lastIndexOfdimulai pada indeks 0, bukan akhir. Itu membuat saya tersandung juga, pada awalnya. Namun, memeriksa apa yang dimulai dengan string adalah tugas umum sehingga JavaScript benar-benar harus memiliki API yang tepat untuk itu, tidak semua idiom dan alternatif yang Anda lihat di halaman ini, betapapun pintar mereka.
Randall Cook
4
Saya lebih suka solusi cobbal daripada Markus. Bahkan jika tanda lebih cepat, dan trik yang mengesankan menggunakan params, sangat sulit dibaca dibandingkan dengan substring.
ThinkBonobo
184

Tanpa fungsi pembantu, hanya menggunakan .testmetode regex :

/^He/.test('Hello world')

Untuk melakukan ini dengan string dinamis daripada yang dikodekan (dengan asumsi bahwa string tidak akan mengandung karakter kontrol regexp):

new RegExp('^' + needle).test(haystack)

Anda harus memeriksa Apakah ada fungsi RegExp.escape di Javascript? jika ada kemungkinan karakter kontrol regexp muncul di string.

Vincent
sumber
1
Untuk membuat ekspresi penggunaan case-sensitive/^he/i
kaizer1v
64

Solusi terbaik:

function startsWith(str, word) {
    return str.lastIndexOf(word, 0) === 0;
}

Dan ini adalah akhir Dengan jika Anda membutuhkannya juga:

function endsWith(str, word) {
    return str.indexOf(word, str.length - word.length) !== -1;
}

Bagi mereka yang lebih suka prototipe ke dalam String:

String.prototype.startsWith || (String.prototype.startsWith = function(word) {
    return this.lastIndexOf(word, 0) === 0;
});

String.prototype.endsWith   || (String.prototype.endsWith = function(word) {
    return this.indexOf(word, this.length - word.length) !== -1;
});

Pemakaian:

"abc".startsWith("ab")
true
"c".ensdWith("c") 
true

Dengan metode:

startsWith("aaa", "a")
true
startsWith("aaa", "ab")
false
startsWith("abc", "abc")
true
startsWith("abc", "c")
false
startsWith("abc", "a")
true
startsWith("abc", "ba")
false
startsWith("abc", "ab")
true
mmm
sumber
Saya pikir Anda telah mencampur lastIndexOf dan indexOf dalam fungsi Anda - beginWith seharusnya mengembalikan str.indexOf (kata, 0) === 0;
Richard Matheson
5
@RichardMatheson masalah dengan menggunakan indexOf adalah bahwa jika gagal cocok di awal, itu akan terus mencari seluruh string, dimana lastIndexOf mulai dari panjang kata dan berjalan kembali ke nol. Oke?
mmm
2
Ahh ya masuk akal sekarang - saya tidak memperhatikan indeks yang Anda gunakan. Trik yang sangat bagus!
Richard Matheson
54

Saya hanya ingin menambahkan pendapat saya tentang ini.

Saya pikir kita bisa menggunakan seperti ini:

var haystack = 'hello world';
var needle = 'he';

if (haystack.indexOf(needle) == 0) {
  // Code if string starts with this substring
}
Mr.D
sumber
2
Jawaban Mark Byers dibandingkan untuk kinerja tiga pendekatan benar berbeda oleh @relfor. Pendekatan yang benar ini tidak disukai karena memerlukan pencarian seluruh string.
maxpolk
@maxpolk Saya pikir indexOfakan berhenti mencari seluruh string ketika menemukan kemunculan pertama. Saya sudah memeriksanya.
Tn.
8
Jika kejadian pertama tidak ditemukan di awal, pendekatan ini mulai tumbuh tidak efisien semakin lama terus mencarinya, berpotensi mencari sampai mencapai akhir, daripada menyerah jauh lebih awal. Karena ada potensi untuk inefisiensi, itu tidak disukai di antara tiga pendekatan yang benar.
maksimal
2
@ Mr.D Dan jika tidak ada yang cocok?
mmm
lain ketika semua tumpukan jerami telah dicari? lebih baik: stackoverflow.com/a/36876507/961018 .. hanya mencari hingga panjang kata
mmm
39

Berikut ini adalah sedikit peningkatan pada solusi CMS:

if(!String.prototype.startsWith){
    String.prototype.startsWith = function (str) {
        return !this.indexOf(str);
    }
}

"Hello World!".startsWith("He"); // true

 var data = "Hello world";
 var input = 'He';
 data.startsWith(input); // true

Memeriksa apakah fungsi sudah ada jika browser masa depan mengimplementasikannya dalam kode asli atau jika itu diterapkan oleh perpustakaan lain. Misalnya, Perpustakaan Prototipe sudah mengimplementasikan fungsi ini.

Penggunaannya !sedikit lebih cepat dan lebih ringkas daripada === 0meski tidak bisa dibaca.

Kit
sumber
1
Ini bisa menjadi masalah: Jika implementasi yang sudah berlaku berbeda dari saya sendiri ini akan merusak aplikasi saya.
Christoph Wurm
2
Ini memiliki masalah O (N) yang dibahas di sini stackoverflow.com/questions/646628/javascript-startswith/…
Chris Moschini
1
menggunakan! ada sangat berantakan
JonnyRaa
-1; menambahkan ini String.prototypeadalah ide yang buruk karena tidak mendekati spesifikasi untuk String.prototype.startsWith. Kode apa pun yang mencoba menggunakan metode ES6 cenderung gagal jika Anda melakukan ini; mungkin terlihat untuk melihat apakah metode sudah didefinisikan, melihat bahwa itu (buruk, oleh Anda) dan tidak menambahkan shim yang sesuai dengan spesifikasi, yang mengarah ke perilaku yang salah nanti.
Mark Amery
21

Lihat juga underscore.string.js . Muncul dengan sekelompok metode pengujian dan manipulasi string yang berguna, termasuk startsWithmetode. Dari dokumen:

dimulai dengan _.startsWith(string, starts)

Metode ini memeriksa apakah stringdimulai dengan starts.

_("image.gif").startsWith("image")
=> true
studgeek
sumber
1
Saya membutuhkan_.string.startsWith
Kolonel Panic
15

Baru-baru ini saya bertanya pada diri sendiri pertanyaan yang sama.
Ada beberapa solusi yang mungkin, berikut 3 yang valid:

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  • s.lastIndexOf(starter, 0) === 0(ditambahkan setelah melihat jawaban Mark Byers )
  • menggunakan loop:

    function startsWith(s,starter) {
      for (var i = 0,cur_c; i < starter.length; i++) {
        cur_c = starter[i];
        if (s[i] !== starter[i]) {
          return false;
        }
      }
      return true;
    }

Saya belum menemukan solusi terakhir yang menggunakan loop.
Anehnya solusi ini mengungguli 3 yang pertama dengan selisih yang signifikan.
Berikut adalah tes jsperf yang saya lakukan untuk mencapai kesimpulan ini: http://jsperf.com/startswith2/2

Perdamaian

ps: ecmascript 6 (harmoni) memperkenalkan startsWithmetode asli untuk string.
Bayangkan berapa banyak waktu yang akan dihemat jika mereka berpikir untuk memasukkan metode yang sangat dibutuhkan ini dalam versi awal itu sendiri.

Memperbarui

Seperti yang ditunjukkan Steve (komentar pertama pada jawaban ini), fungsi khusus di atas akan menimbulkan kesalahan jika awalan yang diberikan lebih pendek dari seluruh string. Dia telah memperbaikinya dan menambahkan optimasi loop yang dapat dilihat di http://jsperf.com/startswith2/4 .

Perhatikan bahwa ada 2 optimisasi loop yang disertakan Steve, yang pertama dari keduanya menunjukkan kinerja yang lebih baik, jadi saya akan memposting kode di bawah ini:

function startsWith2(str, prefix) {
  if (str.length < prefix.length)
    return false;
  for (var i = prefix.length - 1; (i >= 0) && (str[i] === prefix[i]); --i)
    continue;
  return i < 0;
}
Raj Nathani
sumber
Lihat rev terbaru. Selain bug dalam versi di atas (itu akan melempar jika string lebih pendek dari awalan), itu juga lebih lambat daripada versi yang lebih dioptimalkan. Lihat jsperf.com/startswith2/4 dan jsperf.com/js-startswith/35 .
Steve Hollasch
^ Terima kasih telah menunjukkan kasus di mana string lebih pendek dari awalan
Raj Nathani
jsperf.com/startswith2/29 => beginWith5 ringkas dan berkinerja sangat baik =)
gtournie
11

Karena ini sangat populer, saya pikir perlu menunjukkan bahwa ada implementasi untuk metode ini dalam ECMA 6 dan dalam persiapan untuk itu orang harus menggunakan polyfill 'resmi' untuk mencegah masalah dan air mata di masa depan.

Untungnya para ahli di Mozilla memberi kami satu:

https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith

if (!String.prototype.startsWith) {
    String.prototype.startsWith = function(searchString, position) {
        position = position || 0;
        return this.indexOf(searchString, position) === position;
    };
}

Harap dicatat bahwa ini memiliki keuntungan diabaikan dengan anggun pada transisi ke ECMA 6.

Scheintod
sumber
5

Solusi berkinerja terbaik adalah berhenti menggunakan panggilan perpustakaan dan hanya mengenali bahwa Anda bekerja dengan dua array. Implementasi linting tangan keduanya pendek dan juga lebih cepat daripada setiap solusi lain yang saya lihat di sini.

function startsWith2(str, prefix) {
    if (str.length < prefix.length)
        return false;
    for (var i = prefix.length - 1; (i >= 0) && (str[i] === prefix[i]); --i)
        continue;
    return i < 0;
}

Untuk perbandingan kinerja (sukses dan gagal), lihat http://jsperf.com/startswith2/4 . (Pastikan Anda memeriksa versi selanjutnya yang mungkin memiliki versi palsu saya.)

Steve Hollasch
sumber
2

Saya baru saja belajar tentang perpustakaan string ini:

http://stringjs.com/

Sertakan file js dan kemudian gunakan Svariabel seperti ini:

S('hi there').endsWith('hi there')

Itu juga dapat digunakan di NodeJS dengan menginstalnya:

npm install string

Kemudian membutuhkannya sebagai Svariabel:

var S = require('string');

Halaman web juga memiliki tautan ke pustaka string alternatif, jika ini tidak sesuai keinginan Anda.

Ashley Davis
sumber
2
  1. Pertanyaannya agak lama, tetapi saya ingin menulis jawaban ini untuk menunjukkan kepada Anda beberapa tolok ukur yang saya buat berdasarkan semua jawaban yang diberikan di sini dan jsperf yang dibagikan oleh Jim Buck.

Saya pada dasarnya membutuhkan cara cepat untuk menemukan apakah jarum panjang berada dalam tumpukan jerami panjang dan mereka sangat mirip kecuali untuk karakter terakhir.

Berikut kode yang saya tulis yang untuk setiap fungsi (sambatan, substring, beginWith, dll.) Menguji keduanya ketika mereka mengembalikan false dan true terhadap string tumpukan jerami ( nestedString) dari 1.000.0001 karakter dan string jarum palsu atau benar 1.000.000 karakter ( testParentStringFalsedan testParentStringTrue, masing-masing):

// nestedString is made of 1.000.001 '1' repeated characters.
var nestedString = '...'

// testParentStringFalse is made of 1.000.000 characters,
// all characters are repeated '1', but the last one is '2',
// so for this string the test should return false.
var testParentStringFalse = '...'

// testParentStringTrue is made of 1.000.000 '1' repeated characters,
// so for this string the test should return true.
var testParentStringTrue = '...'

// You can make these very long strings by running the following bash command
// and edit each one as needed in your editor
// (NOTE: on OS X, `pbcopy` copies the string to the clipboard buffer,
//        on Linux, you would probably need to replace it with `xclip`):
// 
//     printf '1%.0s' {1..1000000} | pbcopy
// 

function testString() {
    let dateStart
    let dateEnd
    let avg
    let count = 100000
    const falseResults = []
    const trueResults = []

    /* slice */
    console.log('========> slice')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.slice(0, testParentStringFalse.length) === testParentStringFalse
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'slice',
        avg
    }
    console.log(`testString() slice = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.slice(0, testParentStringTrue.length) === testParentStringTrue
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'slice',
        avg
    }
    console.log(`testString() slice = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== slice')
    console.log('')
    /* slice END */

    /* lastIndexOf */
    console.log('========> lastIndexOf')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.lastIndexOf(testParentStringFalse, 0) === 0
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'lastIndexOf',
        avg
    }
    console.log(`testString() lastIndexOf = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.lastIndexOf(testParentStringTrue, 0) === 0
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'lastIndexOf',
        avg
    }
    console.log(`testString() lastIndexOf = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== lastIndexOf')
    console.log('')
    /* lastIndexOf END */

    /* indexOf */
    console.log('========> indexOf')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.indexOf(testParentStringFalse) === 0
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'indexOf',
        avg
    }
    console.log(`testString() indexOf = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.indexOf(testParentStringTrue) === 0
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'indexOf',
        avg
    }
    console.log(`testString() indexOf = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== indexOf')
    console.log('')
    /* indexOf END */

    /* substring */
    console.log('========> substring')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.substring(0, testParentStringFalse.length) === testParentStringFalse
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'substring',
        avg
    }
    console.log(`testString() substring = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.substring(0, testParentStringTrue.length) === testParentStringTrue
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'substring',
        avg
    }
    console.log(`testString() substring = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== substring')
    console.log('')
    /* substring END */

    /* startsWith */
    console.log('========> startsWith')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.startsWith(testParentStringFalse)
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'startsWith',
        avg
    }
    console.log(`testString() startsWith = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.startsWith(testParentStringTrue)
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'startsWith',
        avg
    }
    console.log(`testString() startsWith = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== startsWith')
    console.log('')
    /* startsWith END */

    falseResults.sort((a, b) => a.avg - b.avg)
    trueResults.sort((a, b) => a.avg - b.avg)

    console.log('false results from fastest to slowest avg:', falseResults)
    console.log('true results from fastest to slowest avg:', trueResults)
}

Saya menjalankan tes benchmark ini di Chrome 75 , Firefox 67 , Safari 12 dan Opera 62 .

Saya belum memasukkan Edge dan IE karena saya tidak memilikinya di mesin ini, tetapi jika seseorang dari Anda ingin menjalankan skrip terhadap Edge dan setidaknya IE 9 dan membagikan hasilnya di sini saya akan sangat penasaran untuk melihat hasilnya.

Hanya ingat bahwa Anda perlu membuat ulang 3 string panjang dan menyimpan skrip dalam file yang kemudian Anda buka di browser Anda karena copy / paste pada konsol browser akan memblokirnya karena setiap panjang string adalah> = 1.000.000).

Berikut ini hasilnya:

Chrome 75 ( substringmenang):

false results from fastest to slowest avg:
1)  {"label":"substring","avg":0.08271}
2)  {"label":"slice","avg":0.08615}
3)  {"label":"lastIndexOf","avg":0.77025}
4)  {"label":"indexOf","avg":1.64375}
5)  {"label":"startsWith","avg":3.5454}

true results from fastest to slowest avg:
1)  {"label":"substring","avg":0.08213}
2)  {"label":"slice","avg":0.08342}
3)  {"label":"lastIndexOf","avg":0.7831}
4)  {"label":"indexOf","avg":0.88988}
5)  {"label":"startsWith","avg":3.55448}

Firefox 67 ( indexOfmenang):

false results from fastest to slowest avg
1)  {"label":"indexOf","avg":0.1807}
2)  {"label":"startsWith","avg":0.74621}
3)  {"label":"substring","avg":0.74898}
4)  {"label":"slice","avg":0.78584}
5)  {"label":"lastIndexOf","avg":0.79668}

true results from fastest to slowest avg:
1)  {"label":"indexOf","avg":0.09528}
2)  {"label":"substring","avg":0.75468}
3)  {"label":"startsWith","avg":0.76717}
4)  {"label":"slice","avg":0.77222}
5)  {"label":"lastIndexOf","avg":0.80527}

Safari 12 ( slicemenang untuk hasil palsu, startsWithmenang untuk hasil nyata, juga Safari adalah yang tercepat dalam hal total waktu untuk melaksanakan seluruh tes):

false results from fastest to slowest avg:
1) "{\"label\":\"slice\",\"avg\":0.0362}"
2) "{\"label\":\"startsWith\",\"avg\":0.1141}"
3) "{\"label\":\"lastIndexOf\",\"avg\":0.11512}"
4) "{\"label\":\"substring\",\"avg\":0.14751}"
5) "{\"label\":\"indexOf\",\"avg\":0.23109}"

true results from fastest to slowest avg:
1) "{\"label\":\"startsWith\",\"avg\":0.11207}"
2) "{\"label\":\"lastIndexOf\",\"avg\":0.12196}"
3) "{\"label\":\"substring\",\"avg\":0.12495}"
4) "{\"label\":\"indexOf\",\"avg\":0.33667}"
5) "{\"label\":\"slice\",\"avg\":0.49923}"

Opera 62 ( substringmenang. Hasil serupa dengan Chrome dan saya tidak terkejut karena Opera didasarkan pada Chromium dan Blink):

false results from fastest to slowest avg:
{"label":"substring","avg":0.09321}
{"label":"slice","avg":0.09463}
{"label":"lastIndexOf","avg":0.95347}
{"label":"indexOf","avg":1.6337}
{"label":"startsWith","avg":3.61454}

true results from fastest to slowest avg:
1)  {"label":"substring","avg":0.08855}
2)  {"label":"slice","avg":0.12227}
3)  {"label":"indexOf","avg":0.79914}
4)  {"label":"lastIndexOf","avg":1.05086}
5)  {"label":"startsWith","avg":3.70808}

Ternyata setiap browser memiliki detail implementasi sendiri (selain Opera, yang didasarkan pada Chromium dan Blink Chrome).

Tentu saja, pengujian lebih lanjut dengan kasus penggunaan yang berbeda dapat dan harus dilakukan (misalnya ketika jarum sangat pendek dibandingkan dengan tumpukan jerami, ketika tumpukan jerami lebih pendek dari jarum, dll ...), tetapi dalam kasus saya, saya perlu membandingkan string yang sangat panjang dan ingin membagikannya di sini.

tonix
sumber
1
var str = 'hol';
var data = 'hola mundo';
if (data.length >= str.length && data.substring(0, str.length) == str)
    return true;
else
    return false;
Chris
sumber
0

Berdasarkan jawaban di sini, ini adalah versi yang saya gunakan sekarang, karena tampaknya memberikan kinerja terbaik berdasarkan pengujian JSPerf (dan secara fungsional lengkap sejauh yang saya tahu).

if(typeof String.prototype.startsWith != 'function'){
    String.prototype.startsWith = function(str){
        if(str == null) return false;
        var i = str.length;
        if(this.length < i) return false;
        for(--i; (i >= 0) && (this[i] === str[i]); --i) continue;
        return i < 0;
    }
}

Ini didasarkan pada beginWith2 dari sini: http://jsperf.com/startswith2/6 . Saya menambahkan tweak kecil untuk peningkatan kinerja kecil, dan sejak itu juga menambahkan cek untuk string perbandingan menjadi nol atau tidak terdefinisi, dan mengubahnya untuk menambah prototipe String menggunakan teknik dalam jawaban CMS.

Perhatikan bahwa implementasi ini tidak mendukung parameter "posisi" yang disebutkan di halaman Jaringan Pengembang Mozilla ini , tetapi itu tampaknya tidak menjadi bagian dari proposal ECMAScript.

Edward Millen
sumber
0

Saya tidak yakin untuk javascript tetapi dalam naskah saya melakukan sesuatu seperti

var str = "something";
(<String>str).startsWith("some");

Saya kira itu harus bekerja pada js juga. Saya harap ini membantu!

Andreas Hadjithoma
sumber
-2

Jika Anda bekerja startsWith()dan endsWith()kemudian Anda harus berhati-hati dalam memimpin ruang. Ini adalah contoh lengkapnya:

var str1 = " Your String Value Here.!! "; // Starts & ends with spaces    
if (str1.startsWith("Your")) { }  // returns FALSE due to the leading spaces…
if (str1.endsWith("Here.!!")) { } // returns FALSE due to trailing spaces…

var str2 = str1.trim(); // Removes all spaces (and other white-space) from start and end of `str1`.
if (str2.startsWith("Your")) { }  // returns TRUE
if (str2.endsWith("Here.!!")) { } // returns TRUE
immayankmodi
sumber
3
Ini adalah perilaku yang sangat tidak standar: string "abc" TIDAK dimulai dengan "abc". Lebih khusus lagi, ECMA 6 tidak mengasumsikan pemangkasan string apa pun, sehingga spasi putih harus benar-benar cocok untuk menghasilkan awal yang cocok.
Steve Hollasch
3
Apa ... bagaimana ini menjawab pertanyaan?
DCShannon
1
@ DCShannon bukan. Ini omong kosong yang tidak bisa dipahami.
Mark Amery
2
@SteveHollasch Niat saya adalah untuk menyadarkan siapa pun yang mencari masalah yang sama yang saya hadapi. Bahwa kita perlu berhati-hati dengan ruang terkemuka saat bekerja startsWith()dan endsWith()berfungsi. Tidak ada lagi!
immayankmodi
-3

Anda juga dapat mengembalikan semua anggota array yang dimulai dengan string dengan membuat prototipe / ekstensi Anda sendiri ke prototipe array, alias

Array.prototype.mySearch = function (target) {
    if (typeof String.prototype.startsWith != 'function') {
        String.prototype.startsWith = function (str){
        return this.slice(0, str.length) == str;
      };
    }
    var retValues = [];
    for (var i = 0; i < this.length; i++) {
        if (this[i].startsWith(target)) { retValues.push(this[i]); }
    }
    return retValues;
};

Dan untuk menggunakannya:

var myArray = ['Hello', 'Helium', 'Hideout', 'Hamster'];
var myResult = myArray.mySearch('Hel');
// result -> Hello, Helium
Nepaluz
sumber