Mundarija (31)
- Bu darsda
- 1. Nega bu kerak?
- 2. To'rt amal — rasmda
- 3. Yangi Set qaytaradigan to'rt metod
- 3.1 union — birlashma
- 3.2 intersection — kesishma
- 3.3 difference — farq
- 3.4 symmetricDifference — simmetrik farq
- 3.5 Asl to'plamlar o'zgarmaydi
- 3.6 Ikkitadan ko'p to'plam
- 4. "Ha yoki yo'q" beradigan uch metod
- 4.1 isSubsetOf va isSupersetOf
- 4.2 isDisjointFrom — umumiy narsa yo'qmi?
- 4.3 Qaysi savolga qaysi metod
- 5. Argument sifatida nima berish mumkin
- 5.1 Massiv — xato
- 5.2 "To'plamga o'xshash" qiymat
- 6. Qayerda ishlaydi
- 7. Ko'p uchraydigan xatolar
- 7.1 Massivni argument qilish
- 7.2 difference da tomonni adashtirish
- 7.3 Natija asl to'plamga yozildi deb kutish
- 7.4 Ma'lumoti bir xil obyektlar
- 8. Mashqlar
- 1-mashq (oson): Ikki kunlik hisobot
- 2-mashq (o'rta): Bobur uchun menyu
- 3-mashq (qiyin): Bron va kelganlar
- 4-mashq: Vazifalar qadami — yopilgan teglar va branch'ni yakunlash
- 9. Real ishda
- Xulosa
- Manbalar
JavaScript Set metodlari: union, intersection, difference va boshqalar
Qisqacha: ES2025 dan
Setda yettita to'plam metodi bor. To'rttasi yangiSetqaytaradi:a.union(b)— ikkalasidagi hammasi,a.intersection(b)— ikkalasida ham borlari,a.difference(b)—ada bor,bda yo'qlari,a.symmetricDifference(b)— faqat bittasida borlari. Uchtasitrue/falseberadi:isSubsetOf,isSupersetOf,isDisjointFrom. Asl to'plamlar o'zgarmaydi.
Bu darsda
- Ikki to'plamning birlashmasi, kesishmasi va farqini bitta metod bilan hisoblay olasiz.
- "Hammasi bormi?", "umumiy narsa bormi?" savollariga
isSubsetOf,isSupersetOf,isDisjointFrombilan javob bera olasiz. - Metodga qanday argument berish mumkinligini (
Set,Map) va massiv nega xato berishini bilasiz. - Bu metodlar qaysi brauzerlarda ishlashini va eski muhit uchun zaxira yozishni bilasiz.
vazifalarda "yopilgan teglar" ni ko'rsatasiz va teglar imkoniyatini yakunlaysiz.
Oldin bilishingiz kerak: Set, Map, filter, Massivda qidirish va tekshirish.
1. Nega bu kerak?
«Bahor»da dushanba va seshanba kunlari qaysi taomlar sotilganini yozib boramiz:
const dushanba = new Set(["osh", "manti", "choy"]);
const seshanba = new Set(["choy", "osh", "somsa"]);Jasur aka to'rtta savol beradi:
- Ikki kunda jami qaysi taomlar sotildi?
- Qaysilari ikkala kunda ham sotildi?
- Dushanba sotilib, seshanba sotilmaganlari qaysi?
- Faqat bitta kunda sotilganlari qaysi?
Set darsida o'rganganlaringiz bilan javob berish mumkin. Masalan, ikkinchi savol:
const dushanba = new Set(["osh", "manti", "choy"]);
const seshanba = new Set(["choy", "osh", "somsa"]);
const ikkalasida = new Set(
[...dushanba].filter((taom) => seshanba.has(taom)),
);
console.log(ikkalasida); // Set(2) { 'osh', 'choy' }Ishlaydi. Lekin har savol uchun spread, filter, has va yana new Set — to'rt qadam. Uchinchi savolda !seshanba.has bo'ladi, to'rtinchisida esa ikki yo'nalishni birlashtirish kerak. Kod uzayadi, xato qilish oson: ! ni unutish yoki to'plamlarni almashtirib yuborish.
2025-yilda JavaScript standartiga (ES2025) to'plamlar bilan ishlaydigan yettita tayyor metod qo'shildi. Yuqoridagi to'rt savolning har biri endi bitta metod.
2. To'rt amal — rasmda
To'plamlar ustida amal — ikki to'plamdan uchinchisini yasash qoidasi. Matematikada ular ustma-ust tushgan doiralar bilan ko'rsatiladi — bunday rasmni Venn diagrammasi deyishadi, maktab matematikasidan tanish bo'lishi mumkin. Har rasmda chap doira — dushanba (D), o'ng doira — seshanba (S). Bo'yalgan qism — metod qaytaradigan natija:
<style>
.venn {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
gap: 0.75rem;
font: 0.95rem/1.4 system-ui, sans-serif;
color: #1f2a24;
}
.venn figure { min-width: 0; margin: 0; text-align: center; }
.venn svg { width: 100%; max-width: 10rem; }
.venn .t { fill: #9fd3b5; }
.venn .oq { fill: #fff; }
.venn .c { fill: none; stroke: #1f6f4a; stroke-width: 2; }
.venn text { font: bold 14px system-ui, sans-serif; fill: #1f2a24; }
.venn code { font-size: 0.85rem; overflow-wrap: anywhere; }
</style>
<div class="venn">
<figure>
<svg viewBox="0 0 160 100" role="img"
aria-label="Ikkala doira to'liq bo'yalgan">
<circle class="t" cx="62" cy="50" r="38"/>
<circle class="t" cx="98" cy="50" r="38"/>
<circle class="c" cx="62" cy="50" r="38"/>
<circle class="c" cx="98" cy="50" r="38"/>
<text x="38" y="55">D</text><text x="112" y="55">S</text>
</svg>
<figcaption><code>D.union(S)</code><br>hammasi</figcaption>
</figure>
<figure>
<svg viewBox="0 0 160 100" role="img"
aria-label="Faqat doiralar ustma-ust tushgan qism bo'yalgan">
<defs><clipPath id="k2">
<circle cx="62" cy="50" r="38"/>
</clipPath></defs>
<circle class="t" cx="98" cy="50" r="38" clip-path="url(#k2)"/>
<circle class="c" cx="62" cy="50" r="38"/>
<circle class="c" cx="98" cy="50" r="38"/>
<text x="38" y="55">D</text><text x="112" y="55">S</text>
</svg>
<figcaption><code>D.intersection(S)</code><br>
ikkalasida</figcaption>
</figure>
<figure>
<svg viewBox="0 0 160 100" role="img"
aria-label="Chap doiraning o'ngga tegmagan qismi bo'yalgan">
<circle class="t" cx="62" cy="50" r="38"/>
<circle class="oq" cx="98" cy="50" r="38"/>
<circle class="c" cx="62" cy="50" r="38"/>
<circle class="c" cx="98" cy="50" r="38"/>
<text x="38" y="55">D</text><text x="112" y="55">S</text>
</svg>
<figcaption><code>D.difference(S)</code><br>
D da bor, S da yo'q</figcaption>
</figure>
<figure>
<svg viewBox="0 0 160 100" role="img"
aria-label="Ikki doira bo'yalgan, umumiy qism oq">
<defs><clipPath id="k4">
<circle cx="62" cy="50" r="38"/>
</clipPath></defs>
<circle class="t" cx="62" cy="50" r="38"/>
<circle class="t" cx="98" cy="50" r="38"/>
<circle class="oq" cx="98" cy="50" r="38" clip-path="url(#k4)"/>
<circle class="c" cx="62" cy="50" r="38"/>
<circle class="c" cx="98" cy="50" r="38"/>
<text x="38" y="55">D</text><text x="112" y="55">S</text>
</svg>
<figcaption><code>D.symmetricDifference(S)</code><br>faqat
bittasida</figcaption>
</figure>
</div>Ikki doira ustma-ust tushgan o'rta qism — "ikkala kunda ham sotilgan" taomlar. Uchinchi rasmga alohida qarang: difference faqat bitta tomonni beradi. Shuning uchun D.difference(S) va S.difference(D) — har xil natija.
3. Yangi Set qaytaradigan to'rt metod
3.1 union — birlashma
Birlashma (union) — ikki to'plamdagi hamma qiymat, har biri bir marta:
const dushanba = new Set(["osh", "manti", "choy"]);
const seshanba = new Set(["choy", "osh", "somsa"]);
console.log(dushanba.union(seshanba));
// Set(4) { 'osh', 'manti', 'choy', 'somsa' }Tartib: avval dushanba dagilar, keyin seshanba dan yangilari. "choy" va "osh" ikkinchi marta qo'shilmadi. Bu — new Set([...dushanba, ...seshanba]) ning qisqa va aniq yozuvi.
3.2 intersection — kesishma
Kesishma (intersection) — ikkala to'plamda ham bor qiymatlar:
const dushanba = new Set(["osh", "manti", "choy"]);
const seshanba = new Set(["choy", "osh", "somsa"]);
const umumiy = dushanba.intersection(seshanba);
console.log(umumiy); // Set(2) { 'osh', 'choy' }«Nega bu kerak?» bo'limidagi to'rt qadamli kod — bitta chaqiruv.
Bitta nozik joy bor: natija tartibi. Metod tezroq ishlashi uchun kichikroq to'plamni aylanadi. To'plamlar teng bo'lsa — chapdagini. Agar argument kichikroq bo'lsa, natija uning tartibida chiqadi:
const katta = new Set([1, 2, 3, 4]);
const kichik = new Set([3, 2]);
console.log(katta.intersection(kichik)); // Set(2) { 3, 2 }Natija { 2, 3 } emas, { 3, 2 } — kichik ning tartibi. Odatda bu muhim emas. Tartib muhim bo'lsa (masalan, ekranga chiqarishda), natijani massivga aylantirib, o'zingiz saralang.
3.3 difference — farq
Farq (difference) — birinchisida bor, ikkinchisida yo'q qiymatlar:
const dushanba = new Set(["osh", "manti", "choy"]);
const seshanba = new Set(["choy", "osh", "somsa"]);
console.log(dushanba.difference(seshanba)); // Set(1) { 'manti' }
console.log(seshanba.difference(dushanba)); // Set(1) { 'somsa' }Bu metodda tartib hal qiluvchi: "kimdan kim ayiriladi". Sonlardagi ayirish kabi: 5 - 3 va 3 - 5 — har xil. O'qishda yordam beradigan gap: "a.difference(b) — a dan b dagilarni olib tashla".
3.4 symmetricDifference — simmetrik farq
Simmetrik farq (symmetric difference) — faqat bittasida bor qiymatlar. Umumiylar chiqarib tashlanadi:
const dushanba = new Set(["osh", "manti", "choy"]);
const seshanba = new Set(["choy", "osh", "somsa"]);
console.log(dushanba.symmetricDifference(seshanba));
// Set(2) { 'manti', 'somsa' }Bu ikki farqning birlashmasi: a.difference(b).union(b.difference(a)). Nomidagi "simmetrik" so'zi shuni bildiradi: to'plamlarni almashtirsangiz ham, qiymatlar bir xil chiqadi (tartibi farq qilishi mumkin).
3.5 Asl to'plamlar o'zgarmaydi
To'rttala metod ham yangi Set qaytaradi. dushanba va seshanba qanday bo'lsa, shunday qoladi:
const dushanba = new Set(["osh", "manti"]);
const seshanba = new Set(["somsa"]);
const hammasi = dushanba.union(seshanba);
console.log(dushanba.size, hammasi.size); // 2 3
console.log(hammasi === dushanba); // falseBu Nusxa bilan o'zgartirish darsidagi toSorted g'oyasi: natija — yangi qiymat, asl ma'lumot buzilmaydi. Natijalarni zanjir qilish ham mumkin: a.union(b).difference(c).
3.6 Ikkitadan ko'p to'plam
Metodlar har safar ikki to'plam bilan ishlaydi. Uch kun, bir hafta yoki bir oy bo'lsa-chi? reduce yordam beradi: u to'plamlarni juft-juft "yig'ib" boradi.
const hafta = [
new Set(["osh", "manti", "choy"]),
new Set(["choy", "osh", "somsa"]),
new Set(["osh", "choy", "lag'mon"]),
];
const harKuni = hafta.reduce((a, b) => a.intersection(b));
const kamidaBirKun = hafta.reduce((a, b) => a.union(b));
console.log(harKuni); // Set(2) { 'osh', 'choy' }
console.log(kamidaBirKun.size); // 5Boshlang'ich qiymat berilmadi, shuning uchun akkumulyator — birinchi kunning to'plami. Har qadamda u keyingi kun bilan kesishadi (yoki birlashadi). Natija — har kuni sotilgan ikki taom va hafta davomida sotilgan besh xil taom.
Ehtiyot bo'ling: bo'sh massivda boshlang'ich qiymatsiz reduce xato beradi (reduce darsidagi tuzoq). Birlashma uchun xavfsiz boshlang'ich qiymat bor — bo'sh to'plam: hafta.reduce((a, b) => a.union(b), new Set()). Kesishma uchun esa bunday qiymat yo'q: bo'sh to'plam bilan kesishma doim bo'sh. Shuning uchun kesishmadan oldin massiv bo'sh emasligini tekshiring.
Tekshirib ko'ring:
A = {1, 2, 3},B = {3, 4}.A.difference(B)vaA.symmetricDifference(B)nima qaytaradi?
Javob
A.difference(B) — {1, 2}: A dan B dagi 3 olib tashlandi. A.symmetricDifference(B) — {1, 2, 4}: umumiy 3 dan tashqari hammasi. Farq 4 da: difference faqat A tomonni ko'radi, simmetrik farq — ikkala tomonni.
O'zingiz to'ldiring. new Set([1, 2]).union(new Set([2, 3])).size — [:3]. new Set([1, 2]).intersection(new Set([2, 3])).size — [:1].
4. "Ha yoki yo'q" beradigan uch metod
Ba'zan yangi to'plam emas, faqat javob kerak. Bunga uchta metod bor — har biri true yoki false qaytaradi.
4.1 isSubsetOf va isSupersetOf
Qism to'plam (subset) — hamma qiymatlari boshqa to'plamda ham bor to'plam. a.isSubsetOf(b) — "a ning hammasi b ichidami?". isSupersetOf — xuddi shu savol, teskari tomondan: "a b ning hammasini o'z ichiga oladimi?".
Real misol — ruxsatlar. Otabek kassa dasturida buyurtmani bekor qilmoqchi. Buning uchun ikki ruxsat kerak:
const kerakli = new Set(["buyurtma:korish", "buyurtma:bekor"]);
const otabek = new Set(["buyurtma:korish", "buyurtma:yaratish"]);
const jasurAka = new Set([
"buyurtma:korish",
"buyurtma:yaratish",
"buyurtma:bekor",
]);
console.log(kerakli.isSubsetOf(otabek)); // false
console.log(kerakli.isSubsetOf(jasurAka)); // true
console.log(jasurAka.isSupersetOf(kerakli)); // trueOtabekda "bekor qilish" ruxsati yo'q — false. Jasur akada hammasi bor — true. Uchinchi qator ikkinchisining aynan o'zi, faqat boshqa tomondan o'qiladi. Qaysi biri o'qishga qulayroq bo'lsa, shuni yozing.
Ikki chegaraviy holat:
const menyu = new Set(["osh", "manti"]);
console.log(new Set().isSubsetOf(menyu)); // true
console.log(menyu.isSubsetOf(menyu)); // trueBo'sh to'plam har qanday to'plamning qismi: "hamma qiymatlari bor" sharti buzilmaydi, chunki qiymatning o'zi yo'q. Bu every dagi qoida bilan bir xil: [].every(...) — doim true. To'plam o'zining qismi ham.
4.2 isDisjointFrom — umumiy narsa yo'qmi?
Kesishmaydigan (disjoint) to'plamlar — bitta ham umumiy qiymati yo'q to'plamlar. Bobur yong'oq va kunjutga allergik. Taom unga mosmi?
const allergiya = new Set(["yong'oq", "kunjut"]);
const somsa = new Set(["un", "go'sht", "piyoz", "kunjut"]);
const manti = new Set(["un", "go'sht", "piyoz"]);
console.log(somsa.isDisjointFrom(allergiya)); // false
console.log(manti.isDisjointFrom(allergiya)); // trueSomsada kunjut bor — false, mos emas. Mantida umumiy narsa yo'q — true. Bu a.intersection(b).size === 0 bilan bir xil, lekin tezroq: metod birinchi umumiy qiymatni topishi bilan to'xtaydi va yangi to'plam yasamaydi.
Tekshirib ko'ring:
new Set(["osh"]).isSupersetOf(new Set())nima qaytaradi?
Javob
true. Savol: "{osh} bo'sh to'plamning hamma qiymatlarini o'z ichiga oladimi?" Bo'sh to'plamda qiymat yo'q — talab bajarildi. Bu «Ikki chegaraviy holat» dagi new Set().isSubsetOf(...) ning teskari tomondan o'qilishi.
4.3 Qaysi savolga qaysi metod
Metod nomini eslab qolish qiyin bo'lsa, savolni o'zbekcha ayting — u metodni o'zi ko'rsatadi:
| Savol | Metod | Natija |
|---|---|---|
| "Ikkalasida jami nima bor?" | union |
Set |
| "Ikkalasida ham nima bor?" | intersection |
Set |
| "A da bor, B da yo'q nima?" | difference |
Set |
| "Faqat bittasida nima bor?" | symmetricDifference |
Set |
| "A ning hammasi B da bormi?" | isSubsetOf |
boolean |
| "A da B ning hammasi bormi?" | isSupersetOf |
boolean |
| "Umumiy narsa yo'qmi?" | isDisjointFrom |
boolean |
Savolda "nima?" bo'lsa — javob to'plam. "-mi?" bo'lsa — javob true yoki false. Bu kursdagi predikat nomlari qoidasi bilan bir xil: mosmi, arzonmi ham "-mi" bilan tugaydi va boolean qaytaradi.
5. Argument sifatida nima berish mumkin
5.1 Massiv — xato
Eng tabiiy urinish — massivni berish:
const menyu = new Set(["osh", "manti"]);
const yangi = menyu.union(["somsa"]);TypeError: The .size property is NaNTarjimasi: ".size xususiyati — NaN". Xabar g'alati, chunki massiv haqida hech narsa demaydi. Sababi: metod argumentdan size ni so'radi. Massivda size yo'q (length bor), undefined songa aylanib NaN berdi. Metod "bu to'plam emas" deb to'xtadi. Tuzatish: menyu.union(new Set(["somsa"])).
5.2 "To'plamga o'xshash" qiymat
Metodlar argumentning turini tekshirmaydi. Ular faqat uch narsani so'raydi: size (son), has (metod) va keys (metod). Shu uchtasi bor qiymat — to'plamga o'xshash (set-like). Set dan tashqari Map ham shunday — uning kalitlari ishlatiladi:
const menyu = new Set(["osh", "manti"]);
const narxlar = new Map([
["somsa", 8000],
["osh", 35000],
]);
const hammasi = menyu.union(narxlar);
console.log(hammasi); // Set(3) { 'osh', 'manti', 'somsa' }
console.log(menyu.difference(narxlar)); // Set(1) { 'manti' }Qulay: narxi yozilgan taomlar Map da bo'lsa, ularni [...narxlar.keys()] qilib Set ga aylantirish shart emas. Natija esa doim Set.
Tekshirib ko'ring:
narxlar—Map: kalitlari"osh","manti","choy".new Set(["osh", "manti"]).isSubsetOf(narxlar)nima qaytaradi?
Javob
true. Map argument bo'lganda faqat uning kalitlari hisobga olinadi. "osh" ham, "manti" ham kalitlar orasida bor — demak to'plam Map kalitlarining qismi. Narxlar (qiymatlar) bu savolda umuman ishtirok etmaydi.
6. Qayerda ishlaydi
Baseline ma'lumotiga ko'ra yettita metod brauzerlarga shu versiyalardan kelgan: Chrome va Edge 122, Firefox 127, Safari 17 (iOS 17). Hammasida birga ishlay boshlagan sana — 2024-yil 11-iyun. Shu kundan ular Baseline'ning "yangi" (newly available) darajasida: hamma asosiy brauzerning so'nggi versiyasida bor.
Keyingi daraja — "keng tarqalgan" (widely available). U yangi imkoniyat hamma asosiy brauzerda paydo bo'lganidan 30 oy o'tgach beriladi. Bu metodlar uchun u 2026-yil dekabr oyiga to'g'ri keladi — hozir (oktyabr) hali yo'q. Amaliy ma'nosi: yangilanmagan eski telefonlarda, masalan iOS 16 da, TypeError: a.union is not a function chiqadi.
Node'da: biz Node 24 da sinab ko'rdik — hammasi ishlaydi; Node 22 da ham bor.
Eski muhit uchun zaxira — bitta qatorli funksiyalar. Ular «Nega bu kerak?» bo'limidagi usul:
function kesishma(a, b) {
return new Set([...a].filter((q) => b.has(q)));
}
function farq(a, b) {
return new Set([...a].filter((q) => !b.has(q)));
}
const d = new Set(["osh", "manti", "choy"]);
const s = new Set(["choy", "osh", "somsa"]);
console.log(kesishma(d, s)); // Set(2) { 'osh', 'choy' }
console.log(d.intersection(s)); // Set(2) { 'osh', 'choy' }
console.log(farq(d, s)); // Set(1) { 'manti' }
console.log(d.difference(s)); // Set(1) { 'manti' }O'z nusxamiz va haqiqiy metod bir xil natija berdi. Endi metodning ichida nima borligini ham bilasiz: aylanish va has. Haqiqiy metod qo'shimcha ravishda kichikroq to'plamni tanlaydi va argument turini tekshiradi.
7. Ko'p uchraydigan xatolar
7.1 Massivni argument qilish
menyu.union(["somsa"]) — TypeError: The .size property is NaN. Tuzatish: new Set([...]) ga o'rang.
7.2 difference da tomonni adashtirish
seshanba.difference(dushanba) o'rniga dushanba.difference(seshanba) yozildi — xatosiz, lekin boshqa javob. Tuzatish: "chapdagidan o'ngdagini olib tashla" deb o'qing. Ikkala tomon kerak bo'lsa — symmetricDifference.
7.3 Natija asl to'plamga yozildi deb kutish
const menyu = new Set(["osh"]);
menyu.union(new Set(["manti"]));
console.log(menyu.size); // 1union yangi Set qaytardi, biz uni hech qayerga saqlamadik — natija yo'qoldi. Tuzatish: const hammasi = menyu.union(...). Asl to'plamning o'zini kengaytirish kerak bo'lsa — eski usul: add.
7.4 Ma'lumoti bir xil obyektlar
To'plam metodlari ham Set dagi qoida bilan solishtiradi: obyektlar havola bo'yicha. Ikki xil { id: 1 } obyekti intersection da uchrashmaydi. Tuzatish: id yoki boshqa primitiv kalitlar to'plami bilan ishlang.
8. Mashqlar
1-mashq (oson): Ikki kunlik hisobot
«Nega bu kerak?» bo'limidagi dushanba va seshanba to'plamlari bilan Jasur akaning to'rt savoliga javob bering. Har javobni massiv ko'rinishida chiqaring.
Yechim
const dushanba = new Set(["osh", "manti", "choy"]);
const seshanba = new Set(["choy", "osh", "somsa"]);
console.log([...dushanba.union(seshanba)]);
console.log([...dushanba.intersection(seshanba)]);
console.log([...dushanba.difference(seshanba)]);
console.log([...dushanba.symmetricDifference(seshanba)]);Konsolda:
[ 'osh', 'manti', 'choy', 'somsa' ]
[ 'osh', 'choy' ]
[ 'manti' ]
[ 'manti', 'somsa' ]Har savolga bitta metod. [...] — natijani massivga aylantirish, chiqishi o'qishga qulay bo'lishi uchun.
2-mashq (o'rta): Bobur uchun menyu
Har taomning tarkibi Map da berilgan: kalit — taom nomi, qiymat — tarkib to'plami. Bobur yong'oq va kunjutga allergik. Unga mos taomlar nomlari massivini qaytaring.
Ishora: [...menyu] juftliklarini filter qiling — shart isDisjointFrom; so'ng map bilan nomlarni oling.
const menyu = new Map([
["osh", new Set(["guruch", "go'sht", "sabzi"])],
["somsa", new Set(["un", "go'sht", "kunjut"])],
["holva", new Set(["un", "shakar", "yong'oq"])],
["manti", new Set(["un", "go'sht", "piyoz"])],
]);
const allergiya = new Set(["yong'oq", "kunjut"]);Yechim
const menyu = new Map([
["osh", new Set(["guruch", "go'sht", "sabzi"])],
["somsa", new Set(["un", "go'sht", "kunjut"])],
["holva", new Set(["un", "shakar", "yong'oq"])],
["manti", new Set(["un", "go'sht", "piyoz"])],
]);
const allergiya = new Set(["yong'oq", "kunjut"]);
const mos = [...menyu]
.filter(([, tarkib]) => tarkib.isDisjointFrom(allergiya))
.map(([nom]) => nom);
console.log(mos); // [ 'osh', 'manti' ]([, tarkib]) — destructuring'da birinchi elementni (nomni) tashlab ketdik, chunki shart uchun faqat tarkib kerak (Massiv destructuring). Somsa kunjut, holva yong'oq tufayli tushib qoldi.
3-mashq (qiyin): Bron va kelganlar
Kechqurun Otabek ikki ro'yxatni solishtiradi: bron qilganlar va haqiqatda kelganlar. bronHisoboti(bronlar, kelganlar) funksiyasini yozing. U ikki massiv oladi va obyekt qaytaradi:
kelmadi— bron qilib kelmaganlar;bronsiz— bronsiz kelganlar;hammasiKeldimi— bron qilganlarning hammasi keldimi (true/false).
Massivlarni avval Set ga aylantiring. Bo'sh bron ro'yxatini ham sinang.
Yechim
function bronHisoboti(bronlar, kelganlar) {
const b = new Set(bronlar);
const k = new Set(kelganlar);
return {
kelmadi: [...b.difference(k)],
bronsiz: [...k.difference(b)],
hammasiKeldimi: b.isSubsetOf(k),
};
}
const bronlar = ["Malika", "Dilshod aka", "Nodira"];
const kelganlar = ["Dilshod aka", "Bobur", "Malika"];
console.log(bronHisoboti(bronlar, kelganlar));
console.log(bronHisoboti([], kelganlar).hammasiKeldimi);Konsolda:
{ kelmadi: [ 'Nodira' ], bronsiz: [ 'Bobur' ], hammasiKeldimi: false }
trueIkki difference — ikki yo'nalish: biri bronlardan kelganlarni, ikkinchisi kelganlardan bronlarni olib tashlaydi. Bron bo'lmasa, hammasiKeldimi — true: bo'sh to'plam har qanday to'plamning qismi. Biznes nuqtai nazaridan ham to'g'ri — kutilgan odam yo'q, demak hech kim kelmay qolmadi.
4-mashq: Vazifalar qadami — yopilgan teglar va branch'ni yakunlash
feature/teglar branch'idagi oxirgi qadam. Teglar qatori hozir har tegning nechta vazifada uchrashini ko'rsatadi. Yangi talab: hamma vazifasi bajarilgan teglarni alohida ayting — bu "yopilgan" ish. Masalan, #bozor teglari bor ikki vazifa ham belgilangan bo'lsa:
Teglar: #bozor — 2, #uy — 1. Yopilgan: #bozor
Yopilgan teg yo'q bo'lsa — qator avvalgidek, qo'shimchasiz.
tegToplami(vazifalar)— berilgan vazifalardagi barcha teglarSeti. Oddiy funksiya,teglariniOlyonida.yopilganTeglar()—VazifalarRoyxatining yangi metodi: bajarilgan vazifalar teglaridan faol vazifalar teglarini ayiring.render()uzayib ketmasin: teglar qatorini alohidateglarniYoz()funksiyasiga chiqaring va unga qo'shimchani qo'shing.
Yechim
teglariniOl dan keyin, klassdan oldin:
function tegToplami(vazifalar) {
return new Set(
vazifalar.flatMap((vazifa) => [...teglariniOl(vazifa.matn)]),
);
}VazifalarRoyxati ichida, tegHisobi dan keyin:
yopilganTeglar() {
const bajarilgan = this.#vazifalar.filter((v) => v.bajarildi);
const faol = this.#vazifalar.filter((v) => !v.bajarildi);
return tegToplami(bajarilgan).difference(tegToplami(faol));
}"4. Chizish" da, render() dan oldin — yangi funksiya. render() dagi teglar qatori uchta qator o'rniga bitta chaqiruv bo'ladi: teglarniYoz();.
function teglarniYoz() {
const sanoq = holat.vazifalar.tegHisobi();
const yopilgan = [...holat.vazifalar.yopilganTeglar()];
const qoshimcha =
yopilgan.length > 0 ? `. Yopilgan: ${yopilgan.join(", ")}` : "";
teglarQatori.hidden = sanoq.size === 0;
matnniYoz(
teglarQatori,
`Teglar: ${teglarMatni(sanoq)}${qoshimcha}`,
);
}Nega difference? "Yopilgan teg" — bajarilgan vazifada bor, lekin birorta faol vazifada yo'q teg. Bu so'zma-so'z difference ning ta'rifi. Faol vazifada ham uchrasa, teg hali ochiq — u natijaga tushmaydi.
Node'da chegaraviy holatlar bilan sinang:
function teglariniOl(matn) {
return new Set(
matn
.toLowerCase()
.split(" ")
.filter((soz) => soz.length > 1 && soz.startsWith("#")),
);
}
function tegToplami(vazifalar) {
return new Set(
vazifalar.flatMap((vazifa) => [...teglariniOl(vazifa.matn)]),
);
}
function yopilganTeglar(vazifalar) {
const bajarilgan = vazifalar.filter((v) => v.bajarildi);
const faol = vazifalar.filter((v) => !v.bajarildi);
return tegToplami(bajarilgan).difference(tegToplami(faol));
}
const vazifalar = [
{ matn: "Sabzi olish #bozor", bajarildi: true },
{ matn: "Guruch olish #bozor #uy", bajarildi: true },
{ matn: "Gilam yuvish #uy", bajarildi: false },
];
console.log(yopilganTeglar(vazifalar));
console.log(yopilganTeglar(vazifalar.slice(0, 2)));
console.log(yopilganTeglar([]).size);Konsolda:
Set(1) { '#bozor' }
Set(2) { '#bozor', '#uy' }
0#uy birinchi holatda yopilmagan — "Gilam yuvish" hali faol. Faol vazifa olib tashlanganda u ham yopildi. Bo'sh ro'yxatda natija bo'sh — qatorga qo'shimcha chiqmaydi.
Brauzerda tekshiring:
- Ochilganda — teglar qatori yashirin, qolgan hamma narsa avvalgidek.
- "Sabzi olish #bozor" va "Guruch olish #bozor #uy" qo'shing —
Teglar: #bozor — 2, #uy — 1. - Avval "Guruch…" ni belgilang —
… Yopilgan: #uy:#bozorhali "Sabzi…" da ochiq. - "Sabzi…" ni ham belgilang —
… Yopilgan: #bozor, #uy. "Guruch…" ni qaytaring —Yopilganyo'qoladi: ikkala teg yana faol vazifada. - «Faol» filtrida ham qator bir xil: teglar butun ro'yxatdan hisoblanadi, filtrdan emas.
Yakunlash. Uch darsda branch'da uch commit to'plandi. Oxirgisini qo'shib, main ga birlashtiring:
git add assets/js/vazifalar.js
git commit -m "Vazifalar: yopilgan teglar (Set.difference)"
git switch main
git merge feature/teglar
git branch -d feature/teglar
git push| Dars | Teglarga nima qo'shildi |
|---|---|
Map |
teglariniOl, royxatda tegHisobi() (Map sanog'i), #teglar qatori |
Set |
teglar takrorsiz va kichik harfda (Set) |
| shu dars | tegToplami, royxatda yopilganTeglar() (difference), teglarniYoz() |
Set.difference iOS 17 dan eski telefonlarda yo'q («Qayerda ishlaydi»). Sizning foydalanuvchilaringiz orasida bunday telefonlar bo'lsa — yopilganTeglar da farq zaxira funksiyasini ishlating.
9. Real ishda
- Ruxsatlar va rollar. "Foydalanuvchida kerakli ruxsatlarning hammasi bormi?" —
isSubsetOf. Admin panellar, API'lar, fayl tizimlari shunday tekshiradi. - Sinxronlash. Serverdagi va telefondagi ro'yxatni solishtirish:
difference— nimani yuklash, teskaridifference— nimani o'chirish kerak. Kontaktlar, sevimlilar, savat. - Filtrlar. Internet do'konda "hamma tanlangan teglar bor mahsulotlar" —
isSubsetOf; "kamida bittasi bor" —isDisjointFromning teskarisi. - Ma'lumot tahlili. "Ikki oyda ham xarid qilgan mijozlar" (
intersection), "ketib qolgan mijozlar" (difference) — marketing hisobotlarining asosi. SQL'da xuddi shu amallarUNION,INTERSECT,EXCEPTdeb ataladi — bazalarni o'rganganda tanish bo'ladi. - Eski kod. 2024-yilgacha bu amallar uchun Lodash kutubxonasining (tayyor yordamchi funksiyalar to'plami, juda ko'p loyihada bor)
_.union,_.intersection,_.differencefunksiyalari ishlatilardi — ular massivlar bilan ishlaydi. Eski loyihalarda ularni ko'p uchratasiz. Yangi kodda o'rnatilganSetmetodlari yetarli, qo'shimcha kutubxona kerak emas. - Intervyu. "Ikki massivning kesishmasini toping" — klassik topshiriq. Endi ikki javobni bilasiz:
filter+has(har joyda ishlaydi) vaintersection(ES2025).
Xulosa
union— hammasi,intersection— ikkalasida,difference— chapda bor o'ngda yo'q,symmetricDifference— faqat bittasida. Hammasi yangiSetqaytaradi.isSubsetOf,isSupersetOf,isDisjointFrom—true/false. Bo'sh to'plam har qanday to'plamning qismi.- Argument — to'plamga o'xshash qiymat (
size,has,keys):SetyokiMap. Massiv —TypeError: The .size property is NaN. differenceda tomon muhim.intersectionnatijasi kichikroq to'plam tartibida bo'lishi mumkin.- Baseline 2024-yil iyunidan (Chrome 122, Firefox 127, Safari 17); eski muhitda —
filter+haszaxirasi.
Keyingi dars: WeakMap, WeakSet, WeakRef va FinalizationRegistry — obyektni xotiradan tozalanishiga to'sqinlik qilmaydigan "kuchsiz" to'plamlar va ular qachon kerakligi.
Manbalar
- MDN: "Set" — "Set composition" bo'limi; "Set.prototype.union()", "Set.prototype.isDisjointFrom()" — developer.mozilla.org
- ECMAScript 2025 Language Specification: "Set.prototype.intersection", "GetSetRecord" — tc39.es/ecma262
- web-features 3.40:
set-methods— github.com/web-platform-dx/web-features
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!