Bir dizenin başka bir dizeyle “StartsWith” olup olmadığını nasıl kontrol edebilirim?


Yanıtlar:


1773

ECMAScript 6'nın String.prototype.startsWith()yöntemini kullanabilirsiniz , ancak henüz tüm tarayıcılarda desteklenmemektedir . Desteklemeyen tarayıcılara eklemek için bir dolgu / çoklu dolgu kullanmak isteyeceksiniz. Spesifikasyonda belirtilen tüm detaylara uyan bir uygulama oluşturmak biraz karmaşıktır. Sadık bir şim istiyorsanız, aşağıdakilerden birini kullanın:

Yöntemi değiştirdikten sonra (veya yalnızca zaten sahip olan tarayıcıları ve JavaScript motorlarını destekliyorsanız), şu şekilde kullanabilirsiniz:

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

var haystack = "Hello world";
var prefix = 'orl';
haystack.startsWith(prefix); // false

Bir dizenin bir dizeyle başlayıp başlamadığını test etmek için en kötü yöntemlerden biri hangisi olabilir? (buradaki yorumunuza bakın: stackoverflow.com/questions/646628/… ) karakter başına karakteri karşılaştırma konusunda daha heveslisiniz. Umarım derleyiciler her dize [index] için bir dize oluşturmak için yeterince akıllı değildir, çünkü sadece şunu yazarsanız: character = string [0] bir nesneyi tahsis edecek, neredeyse LW kullanmaya başlayacaktır (startsWith) )
Martijn Scheffer

@MartijnScheffer: Cevap, cevapladığımdan beri birçok kez düzenlendi ve şimdi tamamen farklı (yorumumu kaldırdım;). ECMAScript 6'nın startsWith yönteminin bunu yapmanın en iyi yolu olduğunu kabul ediyorum.
gtournie

6
@GrahamLaight, 'IE' tarafından desteklendiğini söylediğinizde, muhtemelen Edge'i kastediyorsunuz demektir. developer.mozilla.org/tr/docs/Web/JavaScript/Reference/…
Marcus

: - Yanıldım eğer @Marcus, özür bilgilerim geldi w3schools.com/jsref/jsref_startswith.asp
Graham Laight

UYARI! Bu jsperf testleri, JIT derlemesinde iyi olan tarayıcılarda çalışmaz. Firefox ve Chrome gibi tarayıcılar bazen bir işlem sonucu atıldığında bunu tanır ve bu nedenle işlemi gerçekleştirmez . Bunun dışında, modern javascript motorları dal tahminini kullanır , bu nedenle test dizeleri her yinelemede farklı olmalıdır.
Aloso

1282

Başka bir alternatif .lastIndexOf:

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

Bu geriye doğru bakar haystackbir oluşum için needledizinden başlayarak 0arasında haystack. Başka bir deyişle, sadece haystackile başlayıp başlamadığını kontrol eder needle.

Prensip olarak, bunun diğer bazı yaklaşımlara göre performans avantajları olmalıdır:

  • Tümünde arama yapmıyor haystack.
  • Yeni bir geçici dize oluşturmaz ve hemen atar.

1
@ Rfcoder89'un hangi davayla ilgili olduğundan emin değilim - jsfiddle.net/jkzjw3w2/1
Gulfaraz Rahman

5
@ rfcoder89 lastIndexOf: parametresinin ikinci parametresinin "aba".lastIndexOf ("a")işaret ettiğiniz gibi 2 olduğuna dikkat edin , ancak "aba".lastIndexOf ("a", 0)0, doğru
maxpolk

1
Çok teşekkür ederim. Android lolipop WebView üzerinde çalışmaz, ancak bu lastIndexOf snippet'i çalışır !!!
Herman

ile lastIndexOf dize bu bütün dizeyi arar böylece başlangıcına ucundan aranır: onun verimsizlik çok uzun dizeleri büyür böylece arama yapmak için.
Willy Wonka

8
@willywonka Hayır, 0 startIndex'iniz değilse, 0 pos'dan aranır ve tek kontrol budur. Dizenin tamamı yalnızca fromIndex> = str.length ise aranır.
greene

588
data.substring(0, input.length) === input

3
@ANeves Ben kesinlikle tarayıcı ve kullanılan verilere bağlıdır şüpheli. Gerçek ölçümler için Ben Weaver'ın cevabına bakınız. Şu anda çalıştırdığım tarayıcıda (Windows'ta Chrome 12.0.742) alt dize başarı için kazanıyor ve regex kazanma için başarısız oldu.
cobbal

4
@cobbal Belki. Ancak .lastIndexOf(input, 0)ilk N karakterlerini karşılaştırırken N .substring(0, input.length) === inputsayımı, verileri N uzunluğuna alt diziler ve sonra da bu N karakterlerini karşılaştırır. Kod optimizasyonu yoksa, bu ikinci sürüm diğerinden daha hızlı olamaz. Beni yanlış anlamayın, asla kendi başınıza önerdiğinizden daha iyi bir şey bulamazdım. :)
ANeves

2
@ANeves Ancak .lastIndexOf, false döndürecek uzun bir dizede tüm dize (O (N)) üzerinde yinelenirken, .substring durumu çok daha küçük bir dizede yinelenir. Çoğunluk başarılar veya yalnızca küçük girdiler bekliyorsanız, .lastIndexOf muhtemelen daha hızlıdır - aksi takdirde .substring muhtemelen daha hızlıdır. .substring, giriş denetlenen dizeden daha uzunsa da bir özel durum riski vardır.
Chris Moschini

14
@ChrisMoschini, Mark Byers'ın çözümünün lastIndexOfsonuna değil, 0 dizininde başladığını unutmayın . Bu da beni başlangıçta harekete geçirdi. Yine de, bir dizenin ne ile başladığını kontrol etmek, JavaScript'in gerçekten bu sayfa için gördüğünüz tüm deyimlere ve alternatiflere değil, bunun için uygun bir API'ye sahip olması gerektiği kadar yaygın bir görevdir.
Randall Cook

4
Mark'ın yerine kobalin çözümünü tercih ederim. İşaretler daha hızlı ve parametreleri kullanan etkileyici bir hile olsa bile, alt dize ile karşılaştırıldığında okumak çok zordur.
ThinkBonobo

184

Bir yardımcı işlevi olmadan, regex'in .testyöntemini kullanarak :

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

Bunu sabit kodlu yerine dinamik bir dize ile yapmak için (dizenin regexp kontrol karakterleri içermeyeceği varsayılarak):

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

Dışarı kontrol etmelisiniz JavaScript bir RegExp.escape işlevi var mı? regexp kontrol karakterlerinin dizede görünme olasılığı varsa.


1
İfadeyi büyük / küçük harfe duyarlı hale getirmek için/^he/i
kaizer1v

64

En iyi çözüm:

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

Ve işte bitiyorBuna ihtiyacınız varsa:

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

Dizeye prototip oluşturmayı tercih edenler için:

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;
});

Kullanımı:

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

Yöntemi ile:

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

Bence lastIndexOf ve indexOf işlevlerini karıştırdınız - startsWith döndürülmelidir str.indexOf (word, 0) === 0;
Richard Matheson

5
@RichardMathes: indexOf kullanmayla ilgili sorun, başlangıçta eşleme başarısız olursa, tüm dizeyi aramaya devam etmesidir, böylece lastIndexOf sözcüğün uzunluğundan başlar ve sıfıra geri gider. Anladım?
27mm

2
Ahh evet şimdi mantıklı - kullandığınız endekslere dikkat etmedim. Çok güzel numara!
Richard Matheson

54

Sadece bu konudaki fikrimi eklemek istedim.

Bence sadece böyle kullanabiliriz:

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

if (haystack.indexOf(needle) == 0) {
  // Code if string starts with this substring
}

2
Mark Byers cevabı @relfor tarafından üç farklı doğru yaklaşımın performansı açısından karşılaştırılmıştır. Bu doğru yaklaşım tüm dizenin aranmasını gerektirdiği için tercih edilmedi.
maxpolk

@maxpolk indexOfİlk kez ortaya çıktığında dizenin tamamını aramayı bırakacağımı düşünüyorum . Kontrol ettim.
21D,

8
İlk olay en başta bulunmazsa, bu yaklaşım, daha uzun süre vazgeçmek yerine, sonuna kadar ulaşana kadar arama yapmaya devam ettikçe, verimsiz büyümeye başlar. Verimsizlik potansiyeli olduğundan, üç doğru yaklaşım arasında tercih edilmez.
maxpolk

2
@ Mr.D Peki bir eşleşme yoksa?
aaa

tüm samanlık arandığında? daha iyi: stackoverflow.com/a/36876507/961018 .. sadece kelime uzunluğuna kadar arama yapıyor
mmm

39

İşte CMS'nin çözümünde küçük bir gelişme:

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

Gelecekteki bir tarayıcının yerel kodda uygulanması veya başka bir kütüphane tarafından uygulanması durumunda işlevin zaten mevcut olup olmadığını kontrol etme. Örneğin, Prototip Kütüphanesi bu işlevi zaten uygular.

Kullanımı !, === 0okunamayacak kadar hafif ve hızlıdır .


1
Bu bir sorun haline gelebilir: Halihazırda uygulanmakta olan uygulama kendimden farklı davranırsa, bu durum başvurumu bozar.
Christoph Wurm


1
kullanarak! çok dağınık
JonnyRaa

1; Bu ekleyerek String.prototypeher yerde yakın uygun gelmez, çünkü kötü bir fikir spec için String.prototype.startsWith. ES6 yöntemini kullanmaya çalışan herhangi bir kod bunu yaparsanız başarısız olur; yöntemin önceden tanımlanıp tanımlanmadığını görmek (iyi, sizin tarafınızdan) olup olmadığını görmek ve daha sonra yanlış davranışa neden olacak şekilde spesifikasyona uygun bir şim eklememek iyi görünebilir.
Mark Amery

21

Ayrıca underscore.string.js dosyasını kontrol edin . Bir startsWithyöntem de dahil olmak üzere bir dizi yararlı dize testi ve manipülasyon yöntemi ile birlikte gelir . Dokümanlardan:

ile başlar _.startsWith(string, starts)

Bu yöntem stringile başlayıp başlamayacağını kontrol eder starts.

_("image.gif").startsWith("image")
=> true

1
İhtiyacım var_.string.startsWith
Albay Panik

15

Geçenlerde kendime aynı soruyu sordum.
Birden fazla olası çözüm var, işte 3 geçerli çözüm:

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  • s.lastIndexOf(starter, 0) === 0(Mark Byers'ın cevabını gördükten sonra eklendi )
  • bir döngü kullanarak:

    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;
    }

Bir döngüden yararlanan son çözüme rastlamadım.
Şaşırtıcı bir şekilde bu çözüm, ilk 3'ü önemli bir farkla geride bırakıyor.
İşte bu sonuca ulaşmak için yaptığım jsperf testi: http://jsperf.com/startswith2/2

Barış

ps: ecmascript 6 (uyum) startsWith, dizeler için yerel bir yöntem sunar.
Sadece bu çok ihtiyaç duyulan yöntemi ilk versiyonun içine dahil etmeyi düşünürlerse ne kadar zamandan tasarruf edileceğini düşünün.

Güncelleme

Steve'in işaret ettiği gibi (bu cevaptaki ilk yorum), yukarıdaki önek , verilen önek tüm dizeden daha kısaysa bir hata atar . Bunu düzeltti ve http://jsperf.com/startswith2/4 adresinden görüntülenebilen bir döngü optimizasyonu ekledi .

Steve'in dahil olduğu 2 döngü optimizasyonu olduğunu unutmayın, ikisinden ilki daha iyi performans gösterdi, bu yüzden aşağıdaki kodu göndereceğim:

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;
}

En son rev. Yukarıdaki sürümdeki hatanın yanı sıra (dize önekten daha kısasa atılacaktır), daha optimize edilmiş bir sürümden de daha yavaştır. Bkz. Jsperf.com/startswith2/4 ve jsperf.com/js-startswith/35 .
Steve Hollasch

^ Dizenin önekten daha kısa olduğu durumu işaretlediğiniz için teşekkürler
Raj Nathani

jsperf.com/startswith2/29 => başlarWith5 özlü ve gerçekten iyi performans =)
gtournie

11

Bu çok popüler olduğu için, ECMA 6'da bu yöntem için bir uygulama olduğunu ve buna hazırlık olarak gelecekteki sorunları ve gözyaşlarını önlemek için 'resmi' çoklu dolguyu kullanması gerektiğini belirtmek gerekir.

Neyse ki Mozilla'daki uzmanlar bize bir tane sunuyor:

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;
    };
}

ECMA 6'ya geçişte bunun göz ardı edilme avantajına sahip olduğunu lütfen unutmayın.


5

En iyi performanslı çözüm kütüphane çağrılarını kullanmayı bırakmak ve sadece iki diziyle çalıştığınızı tanımaktır. Elle yapılan bir uygulama, burada gördüğüm diğer tüm çözümlerden hem kısa hem de daha hızlıdır.

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;
}

Performans karşılaştırmaları (başarı ve başarısızlık) için bkz. Http://jsperf.com/startswith2/4 . (Madeni boğmuş olabilecek sonraki sürümleri kontrol ettiğinizden emin olun.)


2

Ben sadece bu dize kütüphanesi hakkında öğrendim:

http://stringjs.com/

Js dosyasını ekleyin ve sonra aşağıdaki Sgibi değişkeni kullanın :

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

NodeJS'de kurarak da kullanılabilir:

npm install string

Sonra Sdeğişken olarak gerektirir :

var S = require('string');

Web sayfanız, süslemenizi almazsa, alternatif dize kitaplıklarına bağlantılar da içerir.


2
  1. Soru biraz eski, ama burada verilen tüm cevaplara ve Jim Buck tarafından paylaşılan jsperf'e dayanarak yaptığım bazı kriterleri göstermek için bu cevabı yazmak istedim.

Temelde uzun bir iğne uzun bir samanlıkta olup olmadığını bulmak için hızlı bir yola ihtiyacım vardı ve son karakterler dışında çok benzerler.

İşte her fonksiyon için (birleştirme, alt dize, startsWith, vb.) Yazdıkları kod, hem nestedString1.000.0001 karakterlik bir samanlık dizesine ( ) hem de 1.000.000 bir sahte veya gerçek iğne dizesine karşı yanlış ve doğru döndüklerinde test eder . karakter ( testParentStringFalseve testParentStringTruesırasıyla):

// 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)
}

Bu karşılaştırma testini Chrome 75 , Firefox 67 , Safari 12 ve Opera 62'de gerçekleştirdim .

Edge ve IE'yi bu makinede kullanmadığım için dahil etmedim, ancak biriniz Edge ve en azından IE 9'a karşı komut dosyasını çalıştırmak ve çıktıyı burada paylaşmak istiyorsa sonuçları görmek çok ilginç olurdu.

Sadece 3 uzun dizeyi yeniden oluşturmanız ve komut dosyasını tarayıcınızda tarayıcının konsolunda kopyala / yapıştır olarak açtığınız bir dosyaya kaydetmeniz gerektiğini unutmayın, çünkü her dizenin uzunluğu> = 1.000.000).

İşte çıktılar:

Chrome 75 ( substringkazanır):

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 ( indexOfkazanır):

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 ( sliceyanlış sonuçlar startsWithiçin kazanır, gerçek sonuçlar için kazanır, ayrıca Safari tüm testi yürütmek için toplam süre açısından en hızlıdır):

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 ( substringkazanır. Sonuçlar Chrome'a ​​benzer ve Opera Chromium ve Blink tabanlı olduğu için şaşırmadım):

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}

Her tarayıcının kendi uygulama ayrıntılarına sahip olduğu ortaya çıkıyor (Chrome'un Chromium ve Blink tabanlı Opera dışında).

Tabii ki, farklı kullanım durumları ile daha fazla test yapılabilir ve yapılmalıdır (örneğin, samanlık ile karşılaştırıldığında iğne gerçekten kısa olduğunda, samanlık iğneden daha kısa olduğunda, vb.), Ancak benim durumumda çok uzun ipleri karşılaştırmam gerekiyordu ve burada paylaşmak istedim.


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

0

Buradaki yanıtlara dayanarak, JSPerf testine dayanan en iyi performansı verdiği gibi (ve söyleyebildiğim kadarıyla işlevsel olarak tamamlandı), bu şimdi kullandığım sürüm.

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;
    }
}

Bu, buradan startWith2'ye dayanıyordu: http://jsperf.com/startswith2/6 . Küçük bir performans iyileştirmesi için küçük bir değişiklik ekledim ve o zamandan beri karşılaştırma dizesinin boş veya tanımsız olması için bir kontrol ekledim ve CMS'nin cevabındaki tekniği kullanarak String prototipine eklemek için dönüştürdüm.

Bu uygulamanın, bu Mozilla Geliştirici Ağı sayfasında belirtilen "position" parametresini desteklemediğini , ancak yine de ECMAScript teklifinin bir parçası gibi görünmediğini unutmayın.


0

Javascript için emin değilim ama daktilo gibi bir şey yaptım

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

Sanırım js üzerinde de çalışmalı. Umut ediyorum bu yardım eder!


-2

Birlikte çalışıyorsanız startsWith()ve endsWith()o zaman önde gelen alanlara dikkat etmelisiniz. İşte tam bir örnek:

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

3
Bu çok standart dışı bir davranıştır: "abc" dizesi "abc" ile BAŞLATILMAZ. Daha spesifik olarak, ECMA 6 herhangi bir dize kesimi kabul etmez, böylece boşluk bir başlangıç ​​sağlamak için tam olarak eşleşmelidir
Steve Hollasch

3
Ne ... bu soruya nasıl cevap veriyor?
DCShannon

1
@DCShannon değil. Bu anlaşılmaz bir saçmalık.
Mark Amery

2
@SteveHollasch Niyetim, karşılaştığım aynı sorunu arayan herkesi tanımaktı. Çalışırken startsWith()ve endsWith()işlevlerde önde gelen alanlara dikkat etmemiz gerekir . Başka hiçbir şey!
immayankmodi

-3

Dizinin prototipine kendi prototipinizi / uzantınızı oluşturarak bir dizeyle başlayan dizinin tüm üyelerini,

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;
};

Ve kullanmak için:

var myArray = ['Hello', 'Helium', 'Hideout', 'Hamster'];
var myResult = myArray.mySearch('Hel');
// result -> Hello, Helium
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.