Տեքստում բառի, սիմվոլի կամ ուղղակի ցանկացած ենթատողի որոնման համար օգտագործվում է մեզ քաջ հայտնի indexOf մեթոդը, որը ~
բիթային օպերատորի հետ օգտագործելու շնորհիվ կարող ենք շատ հետաքրքիր բան անել: Նախ բերեք վերհիշենք,թե ինչպես է վերոհիշյալ մեթոդը աշխատում։ Նա որպես առաջին արգումենտ ստանում է բառը, սիմվոլը կամ ենթատողը, որն ուզում ենք գտնել, իսկ որպես երկրորդ արգումենտ՝ այն դիրքը, որտեղից ուզում ենք որ որոնումը կատարվի։ Ահա նրա գրելաձևը՝
str.indexOf(searchValue, [fromIndex])
, որտեղ․
-
searchValue
- բառը, սիմվոլը կամ ենթատողն է, որն ուզում ենք որոնել։ -
fromIndex
- սա ոչ պարտադիր (օպցիոնալ) երկրորդ պարամետրն է, այն նշում է դիրքը, որտեղից անհրաժեշտ է որոնումը կատարել։ Կարող է լինել ցանկացած ամբողջ թիվ։ Եթե մենք այն չենք նշում, ապա որպես սկզբնական արժեք դիտարկվում է 0-ն, այսինքն որոնումը կատարվում է ամենասկզբից՝ 0 ինդեքսից։ ԵթեfromIndex < 0
, ապա որոնումը կատարվում է ամբողջ տեքստում (այնպես, ինչպես եթե այն լիներ 0), իսկ եթե այն մեծ է տողի երկարությունից՝fromIndex >= str.length
, ապա որոնումը կվերադարձնի -1, բացառությամբ այն դեպքի, երբsearchValue
-ն հավասար է դատարկ տողի։ Վերջինի դեպքում այն ուղղակի կվերադարձնի տողի երկարությունը ՝str.length
։
Որոնումը կատարվում է հետևյալ կերպ, մեթոդը վերադարձնում է տրված ենթատողի ինդեքսը, եթե տեքստը այն պարունակում է, հակառակ դեպքում վերադարձնում է -1։ Օրինակ՝
const str =
"Greater Armenia is the name given to the state of Armenia that emerged on the Armenian Highlands under the reign of King Artaxias I at the turn of the second century BC.";
Գտնենք "Armenia" բառի դիրքը վերևի տեքստի մեջ
const result = str.indexOf("Armenia");
console.log(result);
Կոնսոլում կարտածվի 8 թիվը, որովհետև "Armenia" բառը սկսվում է 8-րդ ինդեքսից (Չենք մոռանում,որ հաշվարկը սկսում ենք 0-ից): Կարելի է նկատել, որ տեքստում 3 անգամ է հիշատակվում "Armenia" բառը, բայց ֆունկցիան մեզ վերադարձնում է առաջին համընկման ինդեքսը։
Նաև, քանի որ ես երկրորդ արգումենտ չէի տվել ֆունկցիային, այն որոնումը սկսեց հենց ամենասկզբից։ Իսկ հիմա փորձենք տալ երկրորդ արգումենտ, որպեսզի որոնումը կատարվի մե՛ր ուզած դիրքից։
const result = str.indexOf("Armenia", 9);
console.log(result);
Կոնսոլում կտպի 50, քանի-որ տեքստի մեջ "Armenia" բառը առաջին անգամ հանդիպում է 50-րդ ինդեքսում, եթե որոնումը կատարվում է սկսած 9-րդ ինդեքսից։ Բացի այս մեթոդից, գոյություն ունի նաև նրա «երկվորյակ» մեթոդը՝ lastIndexOf
-ը։ Աշխատանքի սկզբունքը հիմնականում նույնն է, այն տարբերությամբ, որ այս մեթոդը որոնումը կատարում է տեքստի վերջից։ Նույնպես ունի 2 պարամետր, երկրորդը կրկին պարտադիր չէ։
Դիտարկենք վերը նշված մեր օրինակի վրա՝
const result = str.lastIndexOf("Armenia");
console.log(result);
Կոնսոլում կտպվի 78, որովհետև տեքստում "Armenia" բառը վերջից հաշված առաջին անգամ հանդիպում է 78-րդ ինդեքսում։ Իսկ հիմա փորձենք մեթոդին տալ նաև երկրորդ արգումենտը․
const result = str.lastIndexOf("Armenia", 40);
console.log(result);
Այս անգամ կոնսոլում կտպվի 8, քանի-որ 40-րդ ինդեքսից սկսած, տեքստի վերջից դեպի առաջ շարժվելով, այն հանդիպում է "Armenia" բառին 8-րդ ինդեքսում։
Ի՞նչ առանձնահատկություն ունի մեթոդը։ Երբ մենք փորձենք մեթոդը օգտագործել if
կառուցվածքի պայմանի մեջ, կարող է չստանանք այն, ինչ նախատեսել էինք։ Բերեմ օրինակ վերևում գրված տեքստը օգտագործելով․
if (str.indexOf("Greater")) {
alert("Համընկնում կա");
}
Եթե կոդը աշխատացնենք, ոչ մի alert էլ չի լինի, բայց մենք պարզ տեսնում ենք, որ տեքստը պարունակում է "Greater" բառը, և ուրեմն ինչու՞մ է կայանում խնդիրը։ Իսկ խնդիրը հետևյալն է՝ indexOf
մեթոդը գտնում է Greater բառը 0-երորդ ինդեքսում, և հետևաբար վերադարձնում է 0։ Իսկ 0-ն ինչպես գիտենք falsy
արժեք է, հետևաբար if
կառուցվածքի պայմանը դառնում է սխալ, և մեր օրինակի դեպքում alert-ը չի կատարվում:
Իսկ այժմ հասկանանք թե ինչ լուծումներ կարող են լինել, բացի str.indexOf("Greater") !== -1
տարբերակից։ Կարելի է հրաժարվել indexOf
մեթոդի կիրառությունից բոլոր այն դեպքերում, երբ մեզ պետք է ստանալ որոնվող բառի ոչ թե կոնկրետ դիրքը, այլ ուղղակի ճշտել այն կա տեքստում թե ոչ։ Դրա համար կարող ենք օգտագործել str.includes մեթոդը, այն վերադարձնում է true
, եթե գտնում է որոնվող բառը, հակառակ դեպքում
false`, և վերևում քննարկված իրավիճակը այլևս չի լինի։
Բայց կա մի նրբություն, includes մեթոդը JavaScript-ում ներդրվել է միայն սկսած ES6-ից, և մինչ այդ այս խնդրի լուծման համար օգտագործվել են այլ մեթոդներ, որոնց մենք պետք է ծանոթ լինենք, քանի որ ծրագրավորողի աշխատանքը ենթադրում է նաև հին ծրագրերի սպասարկում ու բարելավում, և մենք հաճախ ենք հանդիպելու այլ լուծումների, քան include մեթոդի օգտագործումն է։
Բացի դրանից մինչև հիմա էլ ահռելի քանակությամբ ծրագրեր են գրվում օգտագործելով ES5 ստանդարտը, և ցանկալի կլինի ծանոթանալ մի շատ հետաքրքիր լուծման հետ՝ օգտագործելով բիթային օպերատոր ~
-ը: «Ինչպես մնացորդով թվերից ստանալ ամբողջ թիվ, և ինչ մեթոդներ կան ստուգելու արդյոք թիվը ամբողջ է թե ոչ» գրառմանս մեջ ես արդեն անդրադարձել եմ ~
օպերատորին, եթե հետաքրքիր է,կարող եք ավելի մանրամասն ծանոթանալ։
Իսկ այստեղ ուղղակի հիշեցնեմ, որ ~n
-ը հավասար է -(n+1)
: Օրինակ՝
-
~1 -ը դառնում է -2 --> -(1+1)
-
~2 -ը դառնում է -3 --> -(2+1)
-
~0 -ն դառնում է -1 --> -(0+1)
Այսպիսով ~n
-ը հավասարվում է 0
-ի այն և միայն այն դեպքում, երբ n
-ը հավասար է -1
-ի։ Հետևաբար if(~str.indexOf("…"))
կառուցվածքում երբ ստուգվի պայմանը, այն 0 կդառնա միայն այն դեպքում, երբ str.indexOf
մեթոդը վերադարձնի -1։ Մենք գիտենք որ մեթոդը -1 վերադարձնում է այն դեպքում, երբ չի կարողանում որևէ համընկնում գտնել։ Հիմա փորձենք այս եղանակը կիրառել մեր վերևի օրինակի վրա․
if (~str.indexOf("Greater")) {
alert("Համընկնում կա");
}
alert-ը կատարվում է, համընկնում կա և ամեն ինչ հրաշալի աշխատում է։ Այս եղանակը կիրառելուց պետք է հաշվի առնել նաև այն, որ ~
օպերատորը «աշխատում է» 32-բիթանոց թվերի հետ, և շատ մեծ տեքստի դեպքում հնարավոր է պրոբլեմներ առաջանան։ Օրինակ ~4294967295-ը նույնպես հավասարվում է 0-ի, բայց գործնականում շատ քիչ դեպքերում է այդպիսի մեծ տեքստերում որոնում կատարելու անհրաժեշտություն առաջանում, իսկ դրանից փոքր թվերի դեպքում այս եղանակը հրաշալի և արդյունավետ աշխատում է։