Come verificare se una stringa "Inizia con" un'altra stringa?


1690

Come scriverei l'equivalente di C # String.StartsWithin JavaScript?

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

haystack.startsWith(needle) == true

Nota: questa è una vecchia domanda e, come sottolineato nei commenti, ECMAScript 2015 (ES6) ha introdotto il .startsWithmetodo. Tuttavia, al momento della stesura di questo aggiornamento (2015) il supporto del browser è lungi dall'essere completo .

Risposte:


1773

È possibile utilizzare il String.prototype.startsWith()metodo ECMAScript 6 , ma non è ancora supportato in tutti i browser . Ti consigliamo di utilizzare uno shim / polyfill per aggiungerlo ai browser che non lo supportano. La creazione di un'implementazione conforme a tutti i dettagli indicati nelle specifiche è un po 'complicata. Se vuoi uno spessore fedele, usa:

Dopo aver ignorato il metodo (o se stai supportando solo browser e motori JavaScript che già lo hanno), puoi usarlo in questo modo:

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

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

@gtournie perché dovrebbe iniziare Quale sarebbe uno dei metodi peggiori per verificare se una stringa inizia con una stringa? (vedi il tuo commento qui: stackoverflow.com/questions/646628/… ) sei più entusiasta di confrontare il personaggio per personaggio. spero che i compilatori siano abbastanza intelligenti da NON generare una stringa per ogni stringa [indice] perché, se scrivi semplicemente questo: character = string [0] assegnerà un oggetto, infinitamente MENO efficiente rispetto all'utilizzo di startWith (startCon cui non assegnerà memoria )
Martijn Scheffer,

@MartijnScheffer: la risposta è stata modificata molte volte da quando ho risposto ed è ora completamente diversa (ho rimosso il mio commento;). Concordo sul fatto che ECMAScript 6 inizia con il metodo è il modo migliore per farlo.
Gtournie,

6
@GrahamLaight, quando dici supportato da "IE", presumibilmente intendi per Edge. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Marcus

@Marcus, mi scuso se ho sbagliato - le mie informazioni sono arrivate da: w3schools.com/jsref/jsref_startswith.asp
Graham Laight,

AVVERTIMENTO! Questi test jsperf non funzionano nei browser adatti alla compilazione JIT. Browser come Firefox e Chrome a volte lo riconoscono quando il risultato di un'operazione viene scartato e quindi non esegue l'operazione . A parte ciò, i moderni motori javascript utilizzano la previsione del ramo , quindi le stringhe di test dovrebbero essere diverse in ogni iterazione.
Aloso,

1283

Un'altra alternativa con .lastIndexOf:

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

Questo guarda indietro haystackper un'occorrenza di needlepartenza dall'indice 0di haystack. In altre parole, controlla solo se haystackinizia con needle.

In linea di principio, ciò dovrebbe avere vantaggi in termini di prestazioni rispetto ad altri approcci:

  • Non cerca l'intero haystack.
  • Non crea una nuova stringa temporanea e quindi la scarta immediatamente.

1
Non sono sicuro di quale caso stia affrontando @ rfcoder89 - jsfiddle.net/jkzjw3w2/1
Gulfaraz Rahman,

5
@ rfcoder89 Nota il secondo parametro di lastIndexOf: "aba".lastIndexOf ("a")è 2 come fai notare, ma "aba".lastIndexOf ("a", 0)è 0, che è corretto
maxpolk

1
Grazie mille. String.startsWith non funziona su Android Lollipop WebView, ma quest'ultimo snippet di LastIndexOf funziona !!!
Herman,

con lastIndexOf la stringa viene ricercato dalla fine all'inizio in modo che cerca l'intera stringa: così la sua inefficienza cresce per stringhe molto lunghe per la ricerca in.
Willy Wonka

8
@willywonka No, non è se hai 0 startIndex, viene cercato da 0 pos ed è l'unico controllo. Viene cercata l'intera stringa solo se fromIndex> = str.length.
greene,

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

3
@ANeves Sospetto che dipenda fortemente dal browser e dai dati utilizzati. Vedi la risposta di Ben Weaver per le misurazioni effettive. Sul browser attualmente sto eseguendo (Chrome 12.0.742 su Windows) le vincite della sottostringa per il successo e le regex preparate vincono per il fallimento.
Cobbal

4
@cobbal Forse. Ma .lastIndexOf(input, 0)confronta i primi N caratteri, mentre .substring(0, input.length) === inputconta N, sottrae i dati alla lunghezza N, quindi confronta quei N caratteri. A meno che non ci sia l'ottimizzazione del codice, questa seconda versione non può essere più veloce dell'altra. Non fraintendetemi, non troverei mai da solo qualcosa di meglio di quanto tu abbia suggerito. :)
ANeves,

2
@ANeves Ma .lastIndexOf su una stringa lunga che restituirà false sta per iterare sull'intera stringa (O (N)), mentre il caso .substring scorre su una stringa potenzialmente molto più piccola. Se ti aspetti successi di maggioranza o solo piccoli input, .lastIndexOf è probabilmente più veloce, altrimenti .substring è probabilmente più veloce. .substring rischia anche un'eccezione se l'input è più lungo della stringa da controllare.
Chris Moschini,

14
@ChrisMoschini, non dimenticare che la soluzione di Mark Byers è lastIndexOfiniziata all'indice 0, non alla fine. Anche questo mi ha fatto inciampare inizialmente. Tuttavia, controllare da cosa inizia una stringa è un'attività così comune che JavaScript dovrebbe davvero avere un'API adeguata per essa, non tutti i modi di dire e le alternative che vedi in questa pagina, per quanto intelligenti siano.
Randall Cook,

4
Preferisco la soluzione di Cobbal rispetto a quella di Mark. Anche se mark's è più veloce e un trucco impressionante usando i parametri, è molto difficile da leggere rispetto alla sottostringa.
ThinkBonobo,

184

Senza una funzione di supporto, basta usare il .testmetodo regex :

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

Per fare ciò con una stringa dinamica piuttosto che con una hardcoded (supponendo che la stringa non conterrà alcun carattere di controllo regexp):

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

Dovresti dare un'occhiata Esiste una funzione RegExp.escape in Javascript? se esiste la possibilità che i caratteri di controllo regexp compaiano nella stringa.


1
Al fine di rendere l'espressione sensibile al maiuscolo / minuscolo/^he/i
kaizer1v

64

Soluzione migliore:

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

Ed ecco qui, anche se ne hai bisogno:

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

Per quelli che preferiscono prototiparlo in 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;
});

Uso:

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

Con metodo:

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

Penso che tu abbia confuso lastIndexOf e indexOf nelle tue funzioni - avvii Dovrebbe essere return str.indexOf (word, 0) === 0;
Richard Matheson,

5
@RichardMatheson il problema con l'utilizzo di indexOf è che se non riesce a trovare una corrispondenza all'inizio, continuerà a cercare l'intera stringa, per cui lastIndexOf inizia dalla lunghezza della parola e torna a zero. Fatto?
mmm

2
Ahh sì, ora ha senso - non ho prestato attenzione agli indici che stavi usando. Trucco molto bello!
Richard Matheson,

54

Volevo solo aggiungere la mia opinione su questo.

Penso che possiamo usare così:

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

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

2
@Relfor ha confrontato la risposta di Mark Byers per le prestazioni di tre diversi approcci corretti. Questo approccio corretto non è stato favorito perché richiede la ricerca dell'intera stringa.
maxpolk,

@maxpolk Penso indexOfche smetterà di cercare l'intera stringa quando trova la prima occorrenza. L'ho controllato.
Mr.D

8
Se la prima occorrenza non si trova all'inizio, questo approccio inizia a diventare inefficiente più a lungo continua a cercarlo, potenzialmente cercando fino a raggiungere la fine, invece di rinunciare molto prima. Poiché esiste un potenziale di inefficienza, non è favorito tra i tre approcci corretti.
maxpolk,

2
@ Mr.D E se non c'è corrispondenza?
mmm,

altrimenti quando è stato perquisito tutto il pagliaio? è meglio: stackoverflow.com/a/36876507/961018 .. cerca solo fino alla lunghezza della parola
mmm

39

Ecco un piccolo miglioramento alla soluzione 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

Verifica se la funzione esiste già nel caso in cui un browser futuro la implementi nel codice nativo o se è implementata da un'altra libreria. Ad esempio, la Libreria prototipi implementa già questa funzione.

L'uso !è leggermente più veloce e più conciso di === 0quanto non sia così leggibile.


1
Questo potrebbe diventare un problema: se l'implementazione già in atto si comporta diversamente dalla mia, ciò rovinerebbe la mia applicazione.
Christoph Wurm,


1
usando! c'è molto
casino

-1; aggiungere questo a String.prototypeè una cattiva idea perché non si avvicina affatto al rispetto delle specifiche per String.prototype.startsWith. Qualsiasi codice che tenta di utilizzare il metodo ES6 potrebbe non riuscire in questo caso; potrebbe ben vedere per vedere se il metodo è già definito, vedere che lo è (male, da te) e non aggiungere uno shim conforme alle specifiche, portando in seguito a un comportamento errato.
Mark Amery,

21

Dai un'occhiata anche a underscore.string.js . Viene fornito con un sacco di utili metodi di test e manipolazione delle stringhe, incluso un startsWithmetodo. Dai documenti:

inizia con _.startsWith(string, starts)

Questo metodo controlla se stringinizia con starts.

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

1
Avevo bisogno_.string.startsWith
il colonnello Panic

15

Di recente mi sono posto la stessa domanda.
Esistono più soluzioni possibili, eccone 3 valide:

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  • s.lastIndexOf(starter, 0) === 0(aggiunto dopo aver visto la risposta di Mark Byers )
  • usando un ciclo:

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

Non ho trovato l'ultima soluzione che utilizza un ciclo.
Sorprendentemente questa soluzione supera i primi 3 di un margine significativo.
Ecco il test jsperf che ho eseguito per giungere a questa conclusione: http://jsperf.com/startswith2/2

Pace

ps: ecmascript 6 (armonia) introduce un startsWithmetodo nativo per le stringhe.
Basti pensare a quanto tempo sarebbe stato risparmiato se avessero pensato di includere questo tanto necessario metodo nella versione iniziale stessa.

Aggiornare

Come ha sottolineato Steve (il primo commento su questa risposta), la funzione personalizzata sopra genererà un errore se il prefisso dato è più corto dell'intera stringa. Lo ha risolto e ha aggiunto un'ottimizzazione del loop che può essere visualizzata su http://jsperf.com/startswith2/4 .

Nota che ci sono 2 ottimizzazioni di loop che Steve ha incluso, il primo dei due ha mostrato prestazioni migliori, quindi posterò quel codice qui sotto:

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

Vedi l'ultimo rev. Oltre al bug nella versione precedente (verrà lanciato se la stringa è più corta del prefisso), è anche più lenta di una versione più ottimizzata. Vedere jsperf.com/startswith2/4 e jsperf.com/js-startswith/35 .
Steve Hollasch,

^ Grazie per aver sottolineato il caso in cui la stringa è più corta del prefisso
Raj Nathani,

jsperf.com/startswith2/29 => startWith5 è conciso ed esegue davvero bene =)
gtournie,

11

Dato che è così popolare, penso che valga la pena sottolineare che esiste un'attuazione per questo metodo nell'ECMA 6 e in preparazione a ciò si dovrebbe usare il polifill "ufficiale" per prevenire futuri problemi e lacrime.

Fortunatamente gli esperti di Mozilla ci forniscono uno:

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

Si noti che ciò ha il vantaggio di essere ignorato con garbo durante la transizione a ECMA 6.


5

La soluzione con le migliori prestazioni è smettere di usare le chiamate in libreria e riconoscere semplicemente che si sta lavorando con due array. Un'implementazione eseguita a mano è breve e anche più veloce di ogni altra soluzione che ho visto qui.

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

Per i confronti delle prestazioni (esito positivo e negativo), consultare http://jsperf.com/startswith2/4 . (Assicurati di controllare le versioni successive che potrebbero aver battuto il mio.)


2

Ho appena imparato a conoscere questa libreria di stringhe:

http://stringjs.com/

Includi il file js e usa la Svariabile in questo modo:

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

Può anche essere utilizzato in NodeJS installandolo:

npm install string

Quindi richiedendolo come Svariabile:

var S = require('string');

La pagina web contiene anche collegamenti a librerie di stringhe alternative, se questa non ti piace.


2
  1. La domanda è un po 'vecchia, ma volevo scrivere questa risposta per mostrarti alcuni parametri di riferimento che ho fatto sulla base di tutte le risposte fornite qui e del jsperf condiviso da Jim Buck.

Fondamentalmente avevo bisogno di un modo rapido per scoprire se un ago lungo si trova all'interno di un lungo pagliaio e sono molto simili, tranne per gli ultimi personaggi.

Ecco il codice che ho scritto che per ogni funzione (giuntura, sottostringa, inizia con, ecc.) Verifica sia quando restituiscono falso che vero contro una stringa di pagliaio ( nestedString) di 1.000.0001 caratteri e una stringa di ago falsa o veritiera di 1.000.000 caratteri ( testParentStringFalsee testParentStringTrue, rispettivamente):

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

Ho eseguito questo test di riferimento su Chrome 75 , Firefox 67 , Safari 12 e Opera 62 .

Non ho incluso Edge e IE perché non li ho su questa macchina, ma se qualcuno di voi vuole eseguire lo script su Edge e almeno IE 9 e condividere l'output qui, sarei molto curioso di vedere i risultati.

Basta ricordare che è necessario ricreare le 3 stringhe lunghe e salvare lo script in un file che si apre nel browser in quanto copia / incolla sulla console del browser lo bloccherà poiché la lunghezza di ogni stringa è> = 1.000.000).

Ecco gli output:

Chrome 75 ( substringvittorie):

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 ( indexOfvince):

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 ( slicevince per risultati falsi, startsWithvince per risultati veri, anche Safari è il più veloce in termini di tempo totale per eseguire l'intero test):

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 ( substringvince. I risultati sono simili a quelli di Chrome e non mi sorprende poiché Opera si basa su Chromium e 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}

Si scopre che ogni browser ha i propri dettagli di implementazione (a parte Opera, che si basa su Chrome Chromium e Blink).

Naturalmente, ulteriori test con diversi casi d'uso potrebbero e dovrebbero essere eseguiti (ad es. Quando l'ago è molto corto rispetto al pagliaio, quando il pagliaio è più corto dell'ago, ecc ...), ma nel mio caso avevo bisogno di confrontare stringhe molto lunghe e volevo condividerlo qui.


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

Sulla base delle risposte qui, questa è la versione che sto usando ora, in quanto sembra offrire le migliori prestazioni in base ai test JSPerf (ed è funzionalmente completa per quanto posso dire).

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

Questo si basava su startWith2 da qui: http://jsperf.com/startswith2/6 . Ho aggiunto una piccola modifica per un piccolo miglioramento delle prestazioni e da allora ho anche aggiunto un controllo per la stringa di confronto che è nulla o non definita, e l'ho convertito per aggiungerlo al prototipo String usando la tecnica nella risposta di CMS.

Nota che questa implementazione non supporta il parametro "position" menzionato in questa pagina della rete di sviluppatori Mozilla , ma che comunque non sembra far parte della proposta ECMAScript.


0

Non sono sicuro per JavaScript ma in dattiloscritto ho fatto qualcosa di simile

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

Immagino che dovrebbe funzionare anche su js. Spero possa essere d'aiuto!


-2

Se stai lavorando con startsWith()e endsWith()poi devi stare attento agli spazi iniziali. Ecco un esempio completo:

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
Questo è un comportamento molto non standard: la stringa "abc" NON inizia con "abc". Più specificamente, ECMA 6 non assume alcun tipo di taglio delle stringhe, quindi gli spazi bianchi devono corrispondere esattamente per produrre un inizio con la corrispondenza.
Steve Hollasch,

3
Cosa ... come risponde alla domanda?
DCShannon,

1
@DCShannon non lo è. È un'assurdità incomprensibile.
Mark Amery,

2
@SteveHollasch La mia intenzione era di conoscere chiunque cercasse lo stesso problema che ho affrontato. Che dobbiamo stare attenti agli spazi guida quando lavoriamo con startsWith()e endsWith()funzioni. Nient'altro!
immayankmodi,

-3

È inoltre possibile restituire tutti i membri di un array che iniziano con una stringa creando il proprio prototipo / estensione sul prototipo di array, ovvero

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

E per usarlo:

var myArray = ['Hello', 'Helium', 'Hideout', 'Hamster'];
var myResult = myArray.mySearch('Hel');
// result -> Hello, Helium
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.