Як перевірити, чи рядок "StartsWith" інший рядок?


1690

Як я можу написати еквівалент C # String.StartsWithв JavaScript?

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

haystack.startsWith(needle) == true

Примітка. Це старе питання, і як зазначалося в коментарях, .startsWithметод ECMAScript 2015 (ES6) представив метод. Однак на момент написання цього оновлення (2015 р.) Підтримка браузера далеко не повна .

Відповіді:


1773

Ви можете використовувати String.prototype.startsWith()метод ECMAScript 6 , але він ще не підтримується у всіх браузерах . Ви хочете використовувати shim / polyfill, щоб додати його до браузерів, які не підтримують його. Створити реалізацію, яка відповідає всім деталям, викладеним у специфікації, є трохи складним. Якщо ви хочете, щоб ви були вірними, використовуйте:

Після того, як ви прошили цей метод (або якщо ви підтримуєте лише браузери та JavaScript, які вже є), ви можете використовувати його так:

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

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

@gtournie, чому початокWith є одним із найгірших методів тестування, якщо рядок починається з рядка? (дивіться свій коментар тут: stackoverflow.com/questions/646628/… ) ви з більшим ентузіазмом порівнюєте персонажів на персонажа. Я сподіваюся, що компілятори досить розумні НЕ генерують рядок для кожної рядки [індекс], тому що, якщо ви просто напишете це: znak = рядок [0], він буде виділяти об'єкт, нескінченно МЕНШЕ ефективніше, ніж використання startWith (пускWith не виділяє жодної пам'яті )
Мартійн Шеффер

@MartijnScheffer: Відповідь редагували багато разів, з тих пір, як я відповів, і зараз зовсім інший (я видалив свій коментар;). Я погоджуюся, що метод startSith ECMAScript 6 - найкращий спосіб зробити це.
gtournie

6
@GrahamLaight, коли ти кажеш, що підтримує "IE", імовірно, ти маєш на увазі Edge. developer.mozilla.org/uk/docs/Web/JavaScript/Reference/…
Марк

@Marcus, вибачте, якщо я помилявся - моя інформація надійшла від: w3schools.com/jsref/jsref_startswith.asp
Graham Laight

УВАГА! Ці тести jsperf не працюють у браузерах, які добре компілюють JIT. Веб-переглядачі, такі як Firefox та Chrome, іноді розпізнають його, коли результат операції відкидається, а тому не виконують цю операцію . Крім того, сучасні javascript-двигуни використовують передбачення гілок , тому тестові рядки повинні бути різними в кожній ітерації.
Aloso

1282

Ще одна альтернатива .lastIndexOf:

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

Це дивиться назад через haystackдля виникнення , needleпочинаючи з індексу 0в haystack. Іншими словами, він перевіряє лише, якщо haystackпочинається з needle.

В принципі, це повинно мати переваги у порівнянні з іншими підходами:

  • Це не пошук усього haystack.
  • Він не створює новий тимчасовий рядок, а потім негайно відкидає його.

1
Не впевнений, про який випадок @ rfcoder89 йдеться - jsfiddle.net/jkzjw3w2/1
Gulfaraz Rahman

5
@ rfcoder89 Зверніть увагу на другий параметр lastIndexOf: "aba".lastIndexOf ("a")це 2, як ви вказуєте, але "aba".lastIndexOf ("a", 0)це 0, що правильно
maxpolk

1
Дуже дякую. String.startsWith не працює на Android-льодяник WebView, але цей останній фрагментIndexOf робить !!!
Герман

з lastIndexOf рядок шукається від кінця до початку, тому він шукає всю нитку: так її неефективність зростає на дуже довгі рядки для пошуку.
willy winka

8
@willywonka Ні, це не так, якщо у вас 0 startIndex, його шукають з 0 позицій, і це єдина перевірка. Весь рядок шукається лише у випадку, якщо fromIndex> = str.length.
Зелена

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

3
@ANeves Я підозрюю, що це сильно залежить від браузера та даних, що використовуються. Дивіться відповідь Бен Вівер про фактичні вимірювання. У веб-переглядачі, на якому я зараз працюю (Chrome 12.0.742 в Windows), підрядок виграє для успіху, і підготовлений регулярний виграш за збій.
кабал

4
@cobbal Можливо. Але .lastIndexOf(input, 0)порівнює перші N символів, тоді як .substring(0, input.length) === inputпідраховує N, підстроковує дані до N довжини, а потім порівнює ці N символів. Якщо немає оптимізації коду, ця друга версія не може бути швидшою за іншу. Не зрозумійте мене неправильно, я ніколи не знайшов би щось краще, ніж ви запропонували. :)
ANeves

2
@ANeves Але .lastIndexOf у довгій строці, яка повернеться помилковою, перейде до всієї рядка (O (N)), тоді як випадок .sststring переводиться на потенційно набагато менший рядок. Якщо ви очікуєте успіху більшості або лише невеликі входи, .lastIndexOf, швидше за все, швидше - в іншому випадку .substring, швидше за все, швидше. .substring також ризикує винятком, якщо вхід довший, ніж перевіряється рядок.
Кріс Москіні

14
@ChrisMoschini, не забувайте, що рішення Марка Байерса lastIndexOfпочинається з індексу 0, а не до кінця. Це спочатку мене теж спонукало. Проте перевірка того, з чого починається рядок, є настільки поширеним завданням, що JavaScript дійсно повинен мати для нього належний API, а не всі ідіоми та альтернативи, які ви бачите на цій сторінці, якими б розумними вони не були.
Randall Cook

4
Я вважаю за краще рішення кабала над Марком. Навіть якщо позначення швидше, і вражаючий трюк за допомогою парам, його читати дуже важко порівняно з підрядком.
ThinkBonobo

184

Без допоміжної функції, просто використовуючи .testметод regex :

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

Для цього потрібно використовувати динамічний рядок, а не жорсткий (за умови, що рядок не буде містити жодних символів керування повторним виведенням):

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

Слід перевірити Чи є функція RegExp.escape у Javascript? якщо існує можливість, щоб символи керування regexp з'являлися в рядку.


1
Для того, щоб зробити вираз чутливим до регістру, використовуйте/^he/i
kaizer1v

64

Найкраще рішення:

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

І ось це закінчується, якщо вам це теж потрібно:

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

Для тих, хто вважає за краще прототипувати його в 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;
});

Використання:

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

З методом:

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

Я думаю, що ви змішали lastIndexOf і indexOf у своїх функціях - startWith повинен бути return str.indexOf (word, 0) === 0;
Річард Матсон

5
@RichardMatheson Проблема з використанням indexOf полягає в тому, що якщо вона не відповідає збігу на початку, вона продовжить пошук по всій рядку, при цьому lastIndexOf починається з довжини слова і повертається до нуля. Зрозумів?
ммм

2
Ага так має сенс зараз - я не звертав уваги на індекси, які ви використовували. Дуже приємний трюк!
Річард Матсон

54

Я просто хотів додати свою думку з цього приводу.

Я думаю, що ми можемо просто використовувати так:

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

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

2
Відповідь Марка Байерса порівнював для виконання трьох різних правильних підходів @relfor. Цей правильний підхід не був сприятливим, оскільки він потребує пошуку по всій рядку.
maxpolk

@maxpolk Я думаю indexOf, що перестане шукати весь рядок, коли знайде перше виникнення. Я це перевірив.
МістерD

8
Якщо перше явище не виявляється на самому початку, цей підхід починає неефективно ставати тим довше, як він продовжує його шукати, потенційно шукаючи, поки не дійде до самого кінця, замість того, щоб здаватися набагато раніше. Оскільки існує потенціал неефективності, він не надається переваги серед трьох правильних підходів.
maxpolk

2
@ Mr.D А якщо немає відповідності?
ммм

інше, коли всі стоги сіна були обшукані? краще: stackoverflow.com/a/36876507/961018 .. шукає лише до довжини слова
ммм

39

Ось незначне вдосконалення рішення 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

Перевірка, чи функція вже існує у випадку, якщо майбутній браузер реалізує її в натурному коді або якщо вона реалізована іншою бібліотекою. Наприклад, бібліотека прототипів вже реалізує цю функцію.

Використання !трохи швидше і стисліше, ніж === 0хоч і не таке читабельне.


1
Це може стати проблемою: Якщо впроваджена програма поводиться інакше, ніж моя власна, це порушить мою програму.
Крістоф Вурм

2
Це проблема O (N) обговорюється тут stackoverflow.com/questions/646628/javascript-startswith/…
Кріс Москіні

1
використовуючи! там дуже безладно
JonnyRaa

-1; додавши , що це String.prototypeпогана ідея , тому що він не приходить де - небудь близько до відповідності з специфікацією для String.prototype.startsWith. Будь-який код, який намагається використовувати метод ES6, може вийти з ладу, якщо ви це робите; цілком можливо, переконаєтесь, що метод вже визначений, побачите, що він є (погано, ви), а не додайте у відповідність специфікаціям, що призводить до неправильної поведінки пізніше.
Марк Амерді

21

Також перегляньте сторінку underscore.string.js . Він постачається з купою корисних методів тестування та маніпулювання рядками, включаючи startsWithметод. З документів:

починаєтьсяЗ _.startsWith(string, starts)

Цей метод перевіряє, чи stringпочинається з starts.

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

1
Мені потрібно_.string.startsWith
полковник Паніка

15

Нещодавно я задав собі те саме питання.
Є кілька можливих рішень, ось 3 дійсних:

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  • s.lastIndexOf(starter, 0) === 0(Додано після перегляду Позначити Байєрс ігрового відповіді )
  • за допомогою циклу:

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

Я не натрапив на останнє рішення, яке використовує цикл.
Дивно, але це рішення значно перевищує перші 3 за значним відривом.
Ось тест jsperf, який я здійснив, щоб дійти такого висновку: http://jsperf.com/startswith2/2

Мир

ps: ecmascript 6 (гармонія) вводить власний startsWithметод для рядків.
Подумайте, скільки часу було б заощаджено, якби вони подумали про включення цього необхідного методу у саму початкову версію.

Оновлення

Як зазначив Стів (перший коментар до цієї відповіді), вищевказана спеціальна функція призведе до помилки, якщо даний префікс буде коротшим за весь рядок. Він це виправив і додав циклічну оптимізацію, яку можна переглянути за адресою http://jsperf.com/startswith2/4 .

Зауважте, що у складі Стіва є дві оптимізації циклу, перша з двох показала кращі показники, тому я опублікую цей код нижче:

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

Дивіться останню версію Крім помилки у вищевказаній версії (вона буде кидатися, якщо рядок буде коротшим за префікс), вона також повільніше, ніж більш оптимізована версія. Див. Jsperf.com/startswith2/4 та jsperf.com/js-startswith/35 .
Стів Холлаш

^ Дякуємо, що
вказали

jsperf.com/startswith2/29 => startWith5 є стислим і справді добре =)
gtournie

11

Оскільки це так популярно, я думаю, що варто зазначити, що для цього методу є реалізація в ECMA 6, і для підготовки до цього слід використовувати "офіційну" поліфункцію для запобігання майбутніх проблем та сліз.

На щастя, експерти Mozilla надають нам одне:

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.


5

Найкраще рішення - припинити використання дзвінків у бібліотеку та просто визнати, що ви працюєте з двома масивами. Ручне прокатне впровадження є коротким, а також швидшим, ніж будь-яке інше рішення, яке я бачив тут.

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

Порівняння продуктивності (успіх і невдача) див . На веб-сайті http://jsperf.com/startswith2/4 . (Переконайтеся, що ви знайдете пізніші версії, які, можливо, натрапили на шахту.)


2

Я щойно дізнався про цю бібліотеку рядків:

http://stringjs.com/

Включіть файл js, а потім скористайтеся такою Sзмінною:

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

Його також можна використовувати в NodeJS, встановивши його:

npm install string

Потім вимагає його як Sзмінної:

var S = require('string');

На веб-сторінці також є посилання на альтернативні бібліотеки рядків, якщо ця не захоплюється.


2
  1. Питання трохи старе, але я хотів написати цю відповідь, щоб показати вам деякі орієнтири, які я зробив, грунтуючись на всіх відповідях, наданих тут, та jsperf, який поділяв Джим Бак.

Мені в основному потрібен був швидкий спосіб виявити, чи довга голка знаходиться в довгій копиці сіна, і вони дуже схожі за винятком останніх символів.

Ось код, який я написав, який для кожної функції (сплайс, підрядка, startWith тощо) перевіряє, коли вони повертають помилкові та істинні проти рядка сіна ( nestedString) в розмірі 1.000.0001 символів та фальшивої чи трикутної голки на рівні 1.000.000 символів ( testParentStringFalseі testParentStringTrueвідповідно):

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

Я пройшов цей тестовий тест на Chrome 75 , Firefox 67 , Safari 12 та Opera 62 .

Я не включив Edge та IE, тому що я не маю їх на цій машині, але якщо хтось із вас хоче запустити сценарій проти Edge та принаймні IE 9 та поділитися результатами, мені було б дуже цікаво побачити результати.

Просто пам’ятайте, що вам потрібно відтворити 3 довгі рядки і зберегти скрипт у файлі, який ви відкриєте у своєму браузері, оскільки копіювати / вставляти на консоль браузера буде блокувати його, оскільки довжина кожної струни> = 1.000.000).

Ось результати:

Chrome 75 ( substringвиграє):

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 ( indexOfвиграє):

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 ( sliceвиграє за хибні результати, startsWithвиграє за справжні результати, також Safari - найшвидший за загальний час, щоб виконати весь тест):

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 ( substringвиграє. Результати схожі на Chrome, і я не здивований, оскільки Opera базується на Chromium and 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}

Виявляється, кожен браузер має свої деталі реалізації (крім Opera, яка базується на Chromium and Blink) Chrome.

Звичайно, подальше випробування в різних випадках використання можна і потрібно проводити (наприклад, коли голка дійсно коротка в порівнянні з копицею сіна, коли сіна коротше голки тощо), але в моєму випадку мені потрібно було порівняти дуже довгі струни і хотів поділитися цим тут.


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

Виходячи з відповідей тут, це версія, яку я зараз використовую, оскільки, здається, дає найкращі показники на основі тестування JSPerf (і є функціонально повною, наскільки я можу сказати).

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

Це було засноване на startWith2 звідси: http://jsperf.com/startswith2/6 . Я додав невелику настройку для невеликого покращення продуктивності, а потім додав чек на те, що рядок порівняння є нульовим або невизначеним, і перетворив його на додавання до прототипу String, використовуючи техніку у відповіді CMS.

Зауважте, що ця реалізація не підтримує параметр "позиція", який згадується на цій сторінці Мережі розробників Mozilla , але це все одно не є частиною пропозиції ECMAScript.


0

Я не впевнений у JavaScript, але в машинописі я щось подібне зробив

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

Я думаю, він повинен працювати і на js. Я сподіваюся, що це допомагає!


-2

Якщо ви працюєте, startsWith()і endsWith()тоді вам слід бути обережними щодо провідних просторів. Ось повний приклад:

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
Це дуже нестандартна поведінка: рядок "abc" НЕ починається з "abc". Більш конкретно, ECMA 6 не передбачає будь-якого виду обрізки рядків, так що пробіл повинен точно збігатися, щоб отримати стартовий збіг.
Стів Холлаш

3
Що ... як це відповідає на питання?
DCShannon

1
@DCShannon це не так. Це незрозуміла нісенітниця.
Марк Амері

2
@SteveHollasch Мій намір полягав у тому, щоб знати, хто шукає тієї самої проблеми, з якою я стикався. Те, що ми потрібно бути обережним з початковими пробілами при роботі з startsWith()і endsWith()функції. Більш нічого!
imayankmodi

-3

Ви також можете повернути всіх членів масиву, які починаються з рядка, створивши власний прототип / розширення до прототипу масиву, він же

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

І використовувати його:

var myArray = ['Hello', 'Helium', 'Hideout', 'Hamster'];
var myResult = myArray.mySearch('Hel');
// result -> Hello, Helium
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.