Set տվյալների կառուցվածքը: Փորձենք համեմատել զանգվածի հետ: Ո՞ր դեպքերում այն հիանալի այլընտրանք կլինի զանգվածին:
Map տվյալների կառուցվածքին նվիրված գրառման մեջ արդեն նշել եմ, որ տվյալների կառուցվածքի ճիշտ ընտրությունը կարող է օգնել գրելու ավելի պարզ, հասկանալի և արագ աշխատող կոդ, շատ դեպքերում ազատելով բարդ կոնստրուկցիաներ կիրառելու կամ լրացուցիչ ստուգումներ կատարելու անհաժեշտությունից։ Ինչպես և Map-ը՝ Set-ը նույնպես JavaScript-ում ներդրվեց 2015 թվականին ընդունված ստանդարտով (ES6 կամ ECMAScript 2015)։
Set-ը շատ նման է մաթեմատիկայում օգտագործվող բազմություն օբյեկտին։ Նույնպես թույլ է տալիս պահպանել ունիկալ տվյալներ՝ առանց որոշակի հերթականության, միայն թե ի տարբերություն մաթեմատիկական բազմության՝ այն պարտադիր պետք է լինի վերջավոր։ Ինչպես որ Map-ը շատ նմանություններ ուներ օբյեկտի հետ, և իրականում որոշ խնդիրների լուծման մեջ հանդիսանում էր այլընտրանք օբյեկտին, այնպես էլ Set-ը ավելի շատ այլընտրանք է հանդիսանում զանգվածներին, և որոշ դեպքերում զանգվածները փոխարինելով Set-ով՝ մենք կարող ենք շահել թե՛ կոդի պարզության և թե՛ արագագործության մեջ։
Set կարող ենք ստեղծել new Set([iterable])
կոնստրուկտորի միջոցով։ Գլխավորն այն է, որ որպես արգումենտ հաղորդենք միայն իտերացվող օբյեկտներ, օրինակ՝ զանգված։
const set = new Set([2, 4, 6, 8, 2, 6]);
console.log(set); // {2, 4, 6, 8}
Set-ի մեթոդներն ու հատկություններն են՝
-
set.add(value)
- Set-ի մեջ ավելացնում է տրված արժեքը։ Եթե այն արդեն պարունակվում է Set-ի մեջ, ոչ մի բան չի անում։ Վերադարձնում է նոր Set-ը։ -
set.delete(value)
- Ջնջում է արժեքը, վերադարձնում է true, եթե մեթոդի կանչի պահին արժեքը եղել է Set-ում, և հաջողությամբ ջնջվել է, և false, եթե կանչի պահին Set-ը նման արժեք չի պարունակել։ -
set.has(value)
- Վերադարձնում է true, եթե Set-ը պարունակում է նման արժեք, հակառակ դեպքում՝ false: -
set.clear
- Ամբողջությամբ «դատարկում» է Set-ը։ -
set.size
- Վերադարձնում է Set-ում պարունակվող էլեմենտների քանակը։
Set-ի էլեմենտները մենք կարող ենք հերթով արտածել, օգտագործելով ինչպես for of
ցիկլը, այնպես էլ forEach
մեթոդը։ Հետաքրքիրն այն է, որ forEach
մեթոդի պարամետրերը նույնպես 3-ն են՝ value
, valueAgain
, և հենց Set
-ը։ Այսինքն ստացվում է, որ արժեքն արգումենտների մեջ հայտնվում է երկու անգամ։ Սա կարող է տարօրինակ համարվել, սակայն հատուկ այդպես է արվել Map-ի հետ հնարավորինս նույնական ինտերֆեյս ունենալու համար։
Այն նաև ունի նույն ներդրված մեթոդները՝ ինչ Map-ը։
-
set.keys
- Վերադարձնում էset
-ի բոլոր արժեքներից բաղկացած իտերացվող օբյեկտ։ -
set.values
- Նույնպես արժեքներից բաղկացած իտերացվող օբյեկտ է վերադարձնում։ Մեթոդը գոյություն ունի զուտMap
-ի հետ համապատասխանության համար։ Իրականում վերադարձնում է լրիվ նույն բանը, ինչ որset.keys
-ը կանչելու դեպքում։ -
set.entries
- Վերադարձնում է իտերացվող օբյեկտ՝ բաղկացած [value, value] զույգից, գոյություն ունի զուտMap
-ի հետ համապատասխանություն ապահովելու համար։
Թվարկենք Set-ի բոլոր ուժեղ կողմերը՝ համեմատած զանգվածների հետ, որոնք հատկապես կարևոր են կոդի արդյունավետության բարձրացման համար․
-
Էլեմենտների որոնումը։ Զանգվածի
indexOf
ևincludes
մեթոդները, որոնք օգտագործվում են զանգվածում տվյալ էլեմենտը գտնելու կամ պարզելու թե զանգվածը արդյոք պարունակում է նման էլեմենտ, դանդաղ են աշխատում։ -
Էլեմենտի հեռացնելը։ Set-ում էլեմենտը հեռացնելու համար ընդամենը պետք է օգտագործել նրա արժեքը։ Զանգվածում տարբեր դիրքերից էլեմենտի հեռացման համար օգտագործում ենք
splice
ևshift
մեթոդները, որոնք ինչպես և վերը նշվածindexOf
-ը ևincludes
-ը՝ համեմատաբար դանդաղ օպերացիաներ են։ Զանգվածների մեջ էլեմենտ հեռացնելուց նման բարձր արդյունավետությամբ աշխատում է միայնpop
մեթոդը։ -
Էլեմենտ ավելացնելը։ Շատ անգամ ավելի արագ է Set-ում ավելացնել նոր էլեմենտ, քան թե զանգվածում՝ օգտագործելով արդեն հիշատակված
splice
և հատկապեսunshift
մեթոդները։ Զանգվածում էլեմենտ ավելացնելիս նման բարձր արդյունավետություն ցուցաբերում է միայնpush
մեթոդը։ -
Աշխատանքը NaN-ի հետ։
indexOf
մեթոդը չի կարող օգտագործվել ստուգելու համար թե արդյոք զանգվածում կա NaN արժեք։ Այնինչ Set-իhas
մեթոդի օգնությամբ դա հնարավոր է անել։ -
Կրկնվող էլեմենտների բացառումը։ Զանգվածի դեպքում պետք կլիներ գրել լրացուցիչ կոդ, Set-ն արդեն իսկ այնպես է ստեղծված, որ կարող է պահպանել միայն ունիկալ արժեք։
Նշենք, որ մեթոդները, որոնք զանգվածն օգտագործում է էլեմենտների որոնման համար, հիմնականում ունեն ալգորիթմական բարդության O(n) արժեք (գծային են): Սա նշանակում է, որ կա ուղիղ կապ զանգվածի չափի և այդ մեթոդների աշխատանքի արագության մեջ։
Ի տարբերություն զանգվածների՝ Set-ի որոնման, էլեմենտ ավելացնելու և հեռացնելու մեթոդների ալգորիթմական բարդությունը O(1) է, այսինքն հաստատուն է, և կապ չունի թե ինչ չափերի է Set-ը։ Թե՛ 10 էլեմենտ, թե 10․000 էլեմենտ ունեցող Set-ի դեպքում մեթոդներն աշխատում են հաստատուն բարդությամբ, ինչը շա՜տ մեծ առավելություն է։
Անգամ սորտավորված զանգվածների դեպքում, երբ օրինակ որոնումը կատարվում է ոչ թե գծային, այլ լոգարիթմական ժամանակում, միևնույնն է Set-ն ավելի արագ է աշխատում։