Mundarija (32)
- Bu darsda
- 1. Nega bu kerak?
- 2. Intl.PluralRules — ko'plik kategoriyasi
- 2.1 select nima qaytaradi
- 2.2 So'zni tanlash
- 2.3 Har tilda nechta kategoriya
- 2.4 Ingliz tili va kasr sonlar
- 2.5 NumberFormat bilan birga
- 2.6 Tartib sonlar: type: "ordinal"
- 3. Intl.ListFormat — ro'yxatni gapga aylantirish
- 3.1 "va" bilan
- 3.2 "yoki" va birliklar
- 3.3 Faqat satrlar
- 4. Intl.DisplayNames — kodlardan nomlar
- 4.1 Davlat, til, valyuta
- 4.2 Til tanlash menyusi
- 4.3 Noma'lum kod va fallback
- 5. Node va Chrome farqi
- 6. Ko'p uchraydigan xatolar
- 6.1 son === 1 bilan ko'plik
- 6.2 Lug'atda other yo'q
- 6.3 select natijasini so'z deb o'ylash
- 6.4 ListFormat ga son berish
- 6.5 DisplayNames da type ni unutish
- 7. Mashqlar
- 1-mashq (oson): Ruscha "N ta taom"
- 2-mashq (o'rta): Inglizcha reyting
- 3-mashq (qiyin): Buyurtma xabari uch tilda
- 4-mashq: Vazifalar qadami — teglar qatori
- 8. Real ishda
- Xulosa
- Manbalar
JavaScript Intl.PluralRules, ListFormat va DisplayNames: ko'plik, ro'yxat va til nomlari
Qisqacha: Uchta kichik, lekin foydali asbob.
Intl.PluralRulessonning ko'plik kategoriyasini aytadi ("one","few","many","other") — so'zni o'zingiz shu kategoriya bo'yicha tanlaysiz.Intl.ListFormatmassivni"osh, manti va lag'mon"ko'rinishida yozadi.Intl.DisplayNameskodni nomga aylantiradi:"UZ"→"Oʻzbekiston","ru"→"ruscha". Chrome 154 daPluralRuleshamma joyda bir xil ishlaydi,ListFormatvaDisplayNamesesa o'zbekchani bilmaydi.
Bu darsda
PluralRules.selectbilan rus va ingliz tilida son bilan so'zni moslashtirasiz:5 заказов,1 order.type: "ordinal"bilan1st,2nd,3rdyasaysiz.ListFormatbilan "va" va "yoki" ro'yxatlarini uch tilda yozasiz.DisplayNamesbilan til tanlash menyusi va davlatlar ro'yxatini kodsiz tarjima bilan to'ldirasiz.- Uchala asbobning Node 24 va Chrome 154 dagi farqini bilasiz.
Oldin bilishingiz kerak: Intl.NumberFormat, Intl.RelativeTimeFormat, Obyekt: kalit-qiymat juftliklari.
1. Nega bu kerak?
«Bahor»ning Telegram boti mijozga xabar yuboradi. O'zbekcha versiyasi oddiy: Sizda 3 ta buyurtma bor. O'zbek tilida sondan keyin so'z o'zgarmaydi: 1 ta buyurtma, 5 ta buyurtma.
Ruscha versiyada Sardor shunday yozdi:
function buyurtmalar(son) {
return son === 1 ? `${son} заказ` : `${son} заказов`;
}
console.log(buyurtmalar(1)); // 1 заказ
console.log(buyurtmalar(2)); // 2 заказов
console.log(buyurtmalar(21)); // 21 заказовIkkalasi ham xato. Rus tilida 2 заказа va 21 заказ bo'lishi kerak. Qoida murakkab: oxirgi raqam, oxirgi ikki raqam, 11–14 istisnolari... RelativeTimeFormat darsida u bu qoidalarni o'zi bilardi (2 дня, 5 дней). Endi o'sha qoidalarga to'g'ridan-to'g'ri murojaat qilamiz.
Botning yana ikki muammosi bor. Biri — buyurtma tarkibi: osh, manti va lag'mon (o'zbekcha), плов, манты и лагман (ruscha). Ikkinchisi — sozlamalardagi til va davlat nomlari. Uchala muammoni ham bugungi asboblar hal qiladi.
2. Intl.PluralRules — ko'plik kategoriyasi
2.1 select nima qaytaradi
const ru = new Intl.PluralRules("ru");
console.log(ru.select(1)); // one
console.log(ru.select(2)); // few
console.log(ru.select(5)); // many
console.log(ru.select(21)); // oneselect so'zni qaytarmaydi. U sonning kategoriyasini — tilning qaysi qoidasiga tushishini aytadi.
Ko'plik kategoriyasi (plural category) — sondan keyingi so'z bir xil shaklni oladigan sonlar guruhi. Xuddi bozordagi rastalar kabi: har son o'z rastasiga qo'yiladi, so'z shaklini esa rasta nomiga qarab tanlaysiz. Rasta nomlari inglizcha va barcha tillar uchun bir xil: zero, one, two, few, many, other.
Muhim: one — "bitta" degani emas. Bu "rus tilida 1 bilan bir xil shakl oladigan sonlar" guruhi. Unga 21, 101, 1001 ham kiradi. few — 2, 3, 4, 22, 23... many — 5–20, 25, 11... Bu ro'yxatni yodlash shart emas — formatlovchi biladi.
2.2 So'zni tanlash
Kategoriya bo'yicha so'zni lug'atdan olamiz:
const ru = new Intl.PluralRules("ru");
const ZAKAZ = {
one: "заказ",
few: "заказа",
many: "заказов",
other: "заказа",
};
function buyurtmalar(son) {
return `${son} ${ZAKAZ[ru.select(son)]}`;
}
for (const son of [1, 2, 5, 11, 21, 22]) {
console.log(buyurtmalar(son));
}Konsolda:
1 заказ
2 заказа
5 заказов
11 заказов
21 заказ
22 заказаZAKAZ[ru.select(son)] — kvadrat qavsda kalit o'rniga ifoda: avval select ishlaydi, uning natijasi ("few") kalit bo'ladi. other — kasr sonlar uchun: 1,5 заказа. Uni ham yozing, aks holda undefined chiqadi.
Bu tartibni qadamma-qadam ko'ring:
Vizualda lug'at qisqa — other siz. Unda son ni 21 dan 1.5 ga o'zgartirsangiz, undefined chiqadi.
2.3 Har tilda nechta kategoriya
Tillar ko'plik shakllari soni bo'yicha juda farq qiladi. Kategoriyalar ro'yxatini resolvedOptions().pluralCategories beradi. Biz Node 24 da bir necha tilni tekshirdik:
- xitoy (zh)faqat other1 ta
- o'zbek (uz)one, other2 ta
- ingliz (en)one, other2 ta
- rus (ru)one, few, many, other4 ta
- arab (ar)zero, one, two, few, many, other6 ta
Manba: Node 24.21.0 (ICU 78.3, CLDR 48): new Intl.PluralRules(til).resolvedOptions().pluralCategories, 2026-10-05
Nimaga qarang: o'zbek tilida ham ikki kategoriya bor — one va other. Lekin o'zbekchada sondan keyin ot ko'plik qo'shimchasini olmaydi: 1 ta buyurtma, 5 ta buyurtma. Shuning uchun o'zbekcha matnda ikkala kategoriyaga bir xil so'z yozasiz. Turk, qozoq va tojik tillari ham ikki kategoriyali. Rus va ukrain — to'rt, arab — olti.
2.4 Ingliz tili va kasr sonlar
const en = new Intl.PluralRules("en");
const ORDER = { one: "order", other: "orders" };
for (const son of [0, 1, 3]) {
console.log(`${son} ${ORDER[en.select(son)]}`);
}Konsolda:
0 orders
1 order
3 ordersIngliz tilida 0 — other: "0 orders". Fransuz tilida esa 0 — one. Shuning uchun "son 1 bo'lsa" degan if hech qaysi tilda ishonchli emas.
Bitta nozik joy: kategoriya sonning qanday ko'rinishiga ham bog'liq. 1 — "one", lekin ekranda 1.0 bo'lsa — "other" ("1.0 stars"). Buning uchun PluralRules ham NumberFormat dagi kasr sozlamalarini qabul qiladi:
const butun = new Intl.PluralRules("en");
const kasrli = new Intl.PluralRules("en", {
minimumFractionDigits: 1,
});
console.log(butun.select(1), kasrli.select(1)); // one otherQoida: PluralRules ga ham, NumberFormat ga ham bir xil sozlama bering — so'z ekrandagi songa mos kelsin.
2.5 NumberFormat bilan birga
Yuqoridagi misollarda sonni o'zimiz qo'shdik: ${son}. Lekin rus tilida kasr vergul bilan yoziladi, minglar esa bo'sh joy bilan ajraladi. Demak sonni Intl.NumberFormat formatlashi, so'zni esa PluralRules tanlashi kerak. Ikkalasi bir juft bo'lib ishlaydi:
const raqam = new Intl.NumberFormat("ru");
const tur = new Intl.PluralRules("ru");
const ZAKAZ = {
one: "заказ",
few: "заказа",
many: "заказов",
other: "заказа",
};
function buyurtmaYoz(son) {
return `${raqam.format(son)} ${ZAKAZ[tur.select(son)]}`;
}
console.log(buyurtmaYoz(1.5)); // 1,5 заказа
console.log(buyurtmaYoz(1000)); // 1 000 заказовOraliq uchun alohida metod bor — selectRange. "1–5 buyurtma" ruschada 1–5 заказов bo'ladi. Rus tilida kategoriyani odatda oraliqning oxirgi soni belgilaydi, boshqa tillarda qoida boshqacha bo'lishi mumkin. Buni ham formatlovchi biladi:
const tur = new Intl.PluralRules("ru");
console.log(tur.selectRange(1, 5)); // many
console.log(tur.selectRange(1, 2)); // fewselectRange — yangiroq imkoniyat (ECMA-402 2023). Node 24 va Chrome 154 da u bir xil ishladi.
2.6 Tartib sonlar: type: "ordinal"
Ingliz tilida reytingda 1st, 2nd, 3rd, 4th yoziladi. Qoidasi yana murakkab: 11th, lekin 21st; 12th, lekin 22nd. type: "ordinal" shu qoidani beradi:
const tartib = new Intl.PluralRules("en", { type: "ordinal" });
const QOSHIMCHA = { one: "st", two: "nd", few: "rd", other: "th" };
function orin(son) {
return `${son}${QOSHIMCHA[tartib.select(son)]}`;
}
console.log([1, 2, 3, 4, 11, 12, 21, 22, 23].map(orin).join(" "));
// 1st 2nd 3rd 4th 11th 12th 21st 22nd 23rdO'zbek va rus tillarida tartib son uchun bitta kategoriya — other. O'zbekchada tartib son doim bir xil yoziladi: 1-o'rin, 21-o'rin.
Tekshirib ko'ring:
new Intl.PluralRules("ru").select(111)nima qaytaradi —onemi?
Javob
"many". Oxirgi raqam 1 bo'lsa ham, oxirgi ikki raqam — 11. Rus tilida 11–14 bilan tugaydigan sonlar doim many: 111 заказов. Shuning uchun "oxirgi raqamga qara" degan qo'lda qoida yetmaydi.
3. Intl.ListFormat — ro'yxatni gapga aylantirish
Diqqat: Bu darsdagi "Konsolda" natijalari Node 24 da olingan. «Ishga tushir» tugmasi kodni brauzeringizda bajaradi, Chrome'da esa
uzuchunListFormatvaDisplayNamesnatijalari boshqacha chiqadi. Sababini «Node va Chrome farqi» bo'limida ochamiz.
3.1 "va" bilan
Buyurtma tarkibini chiqarish kerak: ["osh", "manti", "lag'mon"]. join(", ") — osh, manti, lag'mon — "va" yo'q. Qo'lda yozish mumkin, lekin ikki element, bitta element, bo'sh massiv holatlarini ham o'ylash kerak. ListFormat hammasini biladi:
const uz = new Intl.ListFormat("uz");
const uchta = ["osh", "manti", "lag'mon"];
console.log(uz.format(uchta)); // osh, manti va lag'mon
console.log(uz.format(["osh", "manti"])); // osh va manti
console.log(uz.format(["osh"])); // osh
console.log(uz.format([])); //Bo'sh massiv — bo'sh satr. Uch tilda:
const taomlar = ["plov", "manti", "lagman"];
console.log(new Intl.ListFormat("ru").format(taomlar));
console.log(new Intl.ListFormat("en").format(taomlar));
console.log(new Intl.ListFormat("en-GB").format(taomlar));Konsolda:
plov, manti и lagman
plov, manti, and lagman
plov, manti and lagmanAmerika inglizchasida and dan oldin ham vergul qo'yiladi — "Oxford comma" deb ataladi. Britaniya inglizchasida — yo'q. Biz buni o'ylamadik ham — til kodi yetarli bo'ldi.
ListFormat da ham formatToParts bor. U ikki xil bo'lak qaytaradi: element — massivdagi qiymat, literal — vergul yoki "va". Masalan, har taom nomini havola qilib, "va" ni oddiy matn qoldirish uchun:
const uz = new Intl.ListFormat("uz");
const qismlar = uz.formatToParts(["osh", "manti"]);
console.log(qismlar.map((q) => `${q.type}:${q.value}`).join(" | "));
// element:osh | literal: va | element:mantiliteral bo'lagida "va" atrofidagi bo'sh joylar ham bor — shuning uchun natijada ikki bo'sh joy ko'rinadi.
3.2 "yoki" va birliklar
type sozlamasi ro'yxat turini tanlaydi:
type |
Ma'nosi | uz natijasi |
|---|---|---|
"conjunction" (standart) |
"va" | Click, Payme va naqd |
"disjunction" |
"yoki" | Click, Payme yoki naqd |
"unit" |
o'lchov bo'laklari | 2 kg 300 g |
"unit" — "2 kg 300 g", "1 soat 30 daqiqa" kabi bo'laklar uchun, ular orasida "va" aytilmaydi. Ingliz tilida u vergul qo'yadi: 2 kg, 300 g.
style — "long", "short", "narrow". Ingliz tilida short — plov, manti, & lagman, narrow — plov, manti, lagman. O'zbekchada long va short bir xil, narrow esa "va" ni tashlab yuboradi.
3.3 Faqat satrlar
const uz = new Intl.ListFormat("uz");
console.log(uz.format(["osh", 5]));TypeError: Iterable yielded 5 which is not a stringTarjimasi: "Iterable 5 ni berdi, u satr emas". format istalgan iterable'ni qabul qiladi (massiv, Set), lekin ichidagi har element satr bo'lishi kerak. Son bo'lsa, avval formatlang: narxlar.map((n) => som.format(n)). Ehtiyot bo'ling: oddiy satr ham iterable — format("abc") xato bermaydi, a, b va c qaytaradi.
Tekshirib ko'ring: Mijoz to'lov usulini tanlashi kerak: "Click yoki Payme". Qaysi
typekerak?
Javob
type: "disjunction". Natija: Click yoki Payme, ruschada — Click или Payme. Standart conjunction esa "Click va Payme" deb yozadi — ma'no o'zgaradi.
4. Intl.DisplayNames — kodlardan nomlar
4.1 Davlat, til, valyuta
Dasturda ma'lumot kod bilan saqlanadi: davlat — "UZ", til — "ru", valyuta — "UZS". Ekranga esa nom kerak. DisplayNames — tayyor tarjima lug'ati:
const davlat = new Intl.DisplayNames("uz", { type: "region" });
const til = new Intl.DisplayNames("uz", { type: "language" });
const valyuta = new Intl.DisplayNames("uz", { type: "currency" });
console.log(davlat.of("UZ"));
console.log(davlat.of("KZ"));
console.log(til.of("ru"));
console.log(til.of("en-US"));
console.log(valyuta.of("UZS"));Konsolda:
Oʻzbekiston
Qozogʻiston
ruscha
ingliz (Amerika)
O‘zbekiston so‘mitype majburiy — formatlovchi qaysi lug'atdan qidirishni bilishi kerak. Qiymatlari:
type |
Kod | uz natijasi |
|---|---|---|
"region" |
"DE", "419" |
Germaniya, Lotin Amerikasi |
"language" |
"tg" |
tojik |
"currency" |
"USD" |
AQSH dollari |
"script" |
"Cyrl" |
kirill |
"calendar" |
"islamic" |
hijriy taqvim |
"dateTimeField" |
"weekday" |
hafta kuni |
Davlat kodi — ikki katta harf (ISO 3166) yoki uch raqam (BMT mintaqa kodi: 419 — Lotin Amerikasi, 150 — Yevropa). Til kodi — Intl.DateTimeFormat darsidagi til kodlari.
Apostroflarga yana qarang: Oʻzbekiston da ʻ (U+02BB), O‘zbekiston so‘mi da ‘ (U+2018). ICU ma'lumotlarining ikki joyidan — ikki xil belgi. Bunday nomni o'z matningiz bilan === orqali solishtirsangiz, false chiqishi mumkin.
4.2 Til tanlash menyusi
Saytdagi til tugmalarida har til o'z tilida yoziladi: o‘zbek, русский, English. Buning uchun har kodni o'sha tilning o'zida so'raymiz:
for (const kod of ["uz", "ru", "en"]) {
const nomlar = new Intl.DisplayNames(kod, { type: "language" });
console.log(`${kod}: ${nomlar.of(kod)}`);
}Konsolda:
uz: o‘zbek
ru: русский
en: EnglishBu — Chrome ham o'zbekcha natija beradigan kam joylardan biri (o‘zbek). Sababini «Node va Chrome» bo'limida ko'ramiz.
4.3 Noma'lum kod va fallback
Kod lug'atda bo'lmasa, standart holatda kodning o'zi qaytadi:
const til = new Intl.DisplayNames("uz", { type: "language" });
const qatiy = new Intl.DisplayNames("uz", {
type: "language",
fallback: "none",
});
console.log(til.of("kaa")); // kaa
console.log(qatiy.of("kaa")); // undefinedkaa — qoraqalpoq tili kodi. O'zbekcha bazada uning nomi yo'q. fallback: "none" bilan undefined qaytadi — shunda o'zingiz zaxira nom qo'yasiz. Chrome 154 da ham undefined. Tekshiruvni ?? "Noma'lum" bilan yozing — u undefined ni ham, null ni ham ushlaydi.
Shakli noto'g'ri kod esa xato tashlaydi: davlat.of("UZB") → RangeError (uch harfli davlat kodi qabul qilinmaydi).
O'zingiz to'ldiring: davlat nomlari uchun type sozlamasiga qiymati beriladi.
5. Node va Chrome farqi
DateTimeFormat, RelativeTimeFormat va NumberFormat darslarida ko'rdik: Chrome 154 da uz lotin ma'lumotlari yo'q, resolvedOptions baribir uz deydi. Bu darsdagi uch asbobda manzara turlicha. Biz darsdagi barcha misollarni Chrome 154 da ham sinadik:
Asbob (uz) |
Node 24 | Chrome 154 |
|---|---|---|
PluralRules |
to'liq | bir xil (barcha tillar) |
ListFormat |
osh, manti va lag'mon |
osh, manti, and lag'mon |
DisplayNames, region "UZ" |
Oʻzbekiston |
Uzbekistan |
DisplayNames, language "ru" |
ruscha |
ru |
DisplayNames, language "uz" |
o‘zbek |
o‘zbek |
Rus va ingliz tillari uchun uchala asbob ikkala muhitda bir xil natija berdi.
Uch xil xulq:
PluralRules— ko'plik qoidalari kichik jadval, Chrome ularni hamma tillar uchun olib yuradi.ListFormat— Chrome o'zbekcha yo'qligini ochiq aytadi:supportedLocalesOf(["uz"])→[],resolvedOptions().locale→ brauzerning o'z tili (bizda"en-US"). Ya'ni brauzer boshqa tilga o'tganini yashirmaydi. Jadvaldagi, andham shuen-USdan —en-GBtilli brauzerda vergulsizandchiqadi.DisplayNames— Chrome "uz bor" deydi (resolvedOptions().locale→"uz", xuddiDateTimeFormatdagidek), lekin nomlar inglizcha (Uzbekistan) yoki kodning o'zi (ru). Faqat tilning o'z nomi (o‘zbek) bor. Ehtimol, Chrome bu nomlarni o'z sozlamalaridagi tillar ro'yxati uchun saqlaydi — lekin bu bizning taxminimiz, hujjatda yozilmagan.
Amaliy xulosa: o'zbekcha ro'yxat yoki davlat nomi brauzerda kerak bo'lsa — natijani tekshiring (format(["a", "b"]) === "a va b") va kerak bo'lsa o'z kichik lug'atingizga o'ting. Yoki matnni serverda yasang.
Tekshirib ko'ring: Nega
ListFormatuchun Chrome'dasupportedLocalesOftekshiruvi ishlaydi,RelativeTimeFormatuchun esa ishlamaydi?
Javob
ListFormat da Chrome o'zbek tili yo'qligini aytadi: supportedLocalesOf(["uz"]) bo'sh massiv qaytaradi. RelativeTimeFormat da esa u ["uz"] deydi, lekin baribir zaxira shablonni ishlatadi. Har asbob o'z ma'lumotlari bilan alohida — shuning uchun eng ishonchli tekshiruv doim natijaning o'zi.
6. Ko'p uchraydigan xatolar
6.1 son === 1 bilan ko'plik
Rus tilida 21 заказ, ingliz tilida 0 orders, fransuz tilida 0 — birlik. "Bitta bo'lsa birlik, aks holda ko'plik" faqat ba'zi tillarda va ba'zi sonlarda to'g'ri. Tuzatish: PluralRules.select + lug'at.
6.2 Lug'atda other yo'q
ZAKAZ[ru.select(1.5)] — other. Lug'atda other bo'lmasa — 1.5 undefined. Tuzatish: har lug'atga tilning barcha kategoriyalarini yozing — ro'yxatini resolvedOptions().pluralCategories dan oling.
6.3 select natijasini so'z deb o'ylash
console.log(\${son} ${ru.select(son)}`)→5 many. select` — kategoriya, so'z emas.
6.4 ListFormat ga son berish
format([35000, 28000]) → TypeError. Tuzatish: avval har elementni NumberFormat bilan satrga aylantiring.
6.5 DisplayNames da type ni unutish
const nomlar = new Intl.DisplayNames("uz");TypeError: invalid_argumentXabar qisqa va tushunarsiz — ICU ichidagi kod. Ma'nosi: "argument noto'g'ri" — bu yerda type yo'q. Xuddi shu matn of("UZB") da RangeError bilan chiqadi. Shunday qisqa xabar ko'rsangiz, type ni va kod shaklini tekshiring.
7. Mashqlar
1-mashq (oson): Ruscha "N ta taom"
taomlarSoni(son) funksiyasi ruscha qaytarsin: 1 блюдо, 2 блюда, 5 блюд, 21 блюдо, 1.5 блюда. Kategoriyalar: one — блюдо, few — блюда, many — блюд, other — блюда. Ishora: lug'at + select.
Yechim
const ru = new Intl.PluralRules("ru");
const BLYUDO = {
one: "блюдо",
few: "блюда",
many: "блюд",
other: "блюда",
};
function taomlarSoni(son) {
return `${son} ${BLYUDO[ru.select(son)]}`;
}
console.log([1, 2, 5, 21, 1.5].map(taomlarSoni).join(", "));
// 1 блюдо, 2 блюда, 5 блюд, 21 блюдо, 1.5 блюда1.5 ruschada 1,5 deb yozilishi kerak. Buni «NumberFormat bilan birga» bo'limidagidek Intl.NumberFormat("ru") bilan tuzatasiz.
2-mashq (o'rta): Inglizcha reyting
«Bahor» filiallari reytingi: [{ nom: "Chilonzor", ball: 4.8 }, { nom: "Yunusobod", ball: 4.9 }, { nom: "Sergeli", ball: 4.5 }]. Ballar bo'yicha kamayish tartibida saralang va inglizcha chiqaring: 1st — Yunusobod (4.9 stars). Ishora: toSorted, type: "ordinal" va "star/stars" uchun oddiy PluralRules — minimumFractionDigits: 1 bilan, chunki ball doim 4.9 ko'rinishida.
Yechim
const tartib = new Intl.PluralRules("en", { type: "ordinal" });
const kategoriya = new Intl.PluralRules("en", {
minimumFractionDigits: 1,
});
const ball = new Intl.NumberFormat("en", {
minimumFractionDigits: 1,
});
const QOSHIMCHA = { one: "st", two: "nd", few: "rd", other: "th" };
const YULDUZ = { one: "star", other: "stars" };
const filiallar = [
{ nom: "Chilonzor", ball: 4.8 },
{ nom: "Yunusobod", ball: 4.9 },
{ nom: "Sergeli", ball: 4.5 },
];
filiallar
.toSorted((a, b) => b.ball - a.ball)
.forEach((f, i) => {
const orin = `${i + 1}${QOSHIMCHA[tartib.select(i + 1)]}`;
const soz = YULDUZ[kategoriya.select(f.ball)];
const baho = `${ball.format(f.ball)} ${soz}`;
console.log(`${orin} — ${f.nom} (${baho})`);
});Konsolda:
1st — Yunusobod (4.9 stars)
2nd — Chilonzor (4.8 stars)
3rd — Sergeli (4.5 stars)Uchta formatlovchi bitta sozlama bilan ishlaydi: ekranda 4.9, ko'plik ham 4.9 uchun tanlanadi. Ball 1 bo'lsa, 1.0 stars chiqadi — ekrandagi 1.0 ga mos.
3-mashq (qiyin): Buyurtma xabari uch tilda
xabarYoz(til, taomlar) — taomlar massivi (o'zbekcha nomlar emas, har tilda alohida beriladi) uchun quyidagini qaytarsin: uz — Buyurtmangiz: osh va manti (2 ta taom), ru — Ваш заказ: плов и манты (2 блюда), en — Your order: plov and manti (2 dishes). Har til uchun matn qoliplarini obyektda saqlang. Ishora: ListFormat, PluralRules; o'zbekcha uchun one va other bir xil.
Yechim
const MATNLAR = {
uz: {
bosh: "Buyurtmangiz",
soz: { one: "ta taom", other: "ta taom" },
},
ru: {
bosh: "Ваш заказ",
soz: { one: "блюдо", few: "блюда", many: "блюд", other: "блюда" },
},
en: {
bosh: "Your order",
soz: { one: "dish", other: "dishes" },
},
};
function xabarYoz(til, taomlar) {
const { bosh, soz } = MATNLAR[til];
const royxat = new Intl.ListFormat(til).format(taomlar);
const tur = new Intl.PluralRules(til).select(taomlar.length);
return `${bosh}: ${royxat} (${taomlar.length} ${soz[tur]})`;
}
console.log(xabarYoz("uz", ["osh", "manti"]));
console.log(xabarYoz("ru", ["плов", "манты"]));
console.log(xabarYoz("en", ["plov", "manti", "tea"]));Konsolda:
Buyurtmangiz: osh va manti (2 ta taom)
Ваш заказ: плов и манты (2 блюда)
Your order: plov, manti, and tea (3 dishes)Kodda bitta ham if (til === ...) yo'q: til farqlari formatlovchilarda va MATNLAR lug'atida. Real loyihalarda aynan shunday tuziladi. i18n (internationalization — dasturni ko'p tilga moslash; so'zning birinchi va oxirgi harfi orasida 18 ta harf bor) kutubxonalari shu g'oyani kengaytiradi.
4-mashq: Vazifalar qadami — teglar qatori
vazifalar ilovasida teglar qatori hozir join(", ") bilan yasaladi: Teglar: #bozor — 2, #uy — 1. Kanon kodni o'zgartirmaymiz. Uning o'rniga kurs/mashqlar/12/17-teglar-royxati/teglar.mjs da teglarMatni(sanoq) ning ListFormat li variantini yozing: Map dan #bozor (2), #uy (1) va #o'quv (1) matnini yasasin. Brauzerda o'zbekcha bo'lmasa, oddiy join(", ") ga qaytsin.
Yechim
const royxat = new Intl.ListFormat("uz");
const UZBEKCHA_BOR = royxat.format(["a", "b"]) === "a va b";
export function teglarMatni(sanoq) {
const qismlar = [...sanoq].map(([teg, soni]) => `${teg} (${soni})`);
return UZBEKCHA_BOR ? royxat.format(qismlar) : qismlar.join(", ");
}
const sanoq = new Map([["#bozor", 2], ["#uy", 1], ["#o'quv", 1]]);
console.log(teglarMatni(sanoq));Konsolda:
#bozor (2), #uy (1) va #o'quv (1)[...sanoq] — Map dan [kalit, qiymat] juftliklari massivi. Node'da UZBEKCHA_BOR — true, Chrome 154 da — false, shuning uchun u yerda #bozor (2), #uy (1), #o'quv (1) chiqadi: "and" emas, oddiy vergul.
git add 12/17-teglar-royxati/teglar.mjs
git commit -m "12/17: teglar qatori ListFormat bilan"8. Real ishda
- Ko'p tilli saytlar (i18n). i18next kutubxonasi kalitlarni
buyurtma_one,buyurtma_few,buyurtma_manyko'rinishida saqlaydi va to'g'ri kalitni aynanIntl.PluralRulesbilan tanlaydi. FormatJS esa ICU MessageFormat sintaksisini ishlatadi:{son, plural, one {# заказ} few {# заказа} many {# заказов} other {# заказа}}— ichida o'sha to'rt kategoriyani taniysiz. - Formalar. Davlat tanlash ro'yxati (
<select>) — kodlar serverdan, nomlarDisplayNamesdan. Yangi til qo'shilganda tarjima qilishga hojat yo'q. - Telegram botlar. Bot serverda — Node'da — ishlaydi, demak
uzma'lumotlari to'liq. Botni kursning backend qismida yozamiz. - Intervyu. "Rus tilida
5 товаровni qanday to'g'ri chiqarasiz?" —PluralRulesni bilish i18n tajribasi borligini ko'rsatadi.
Xulosa
PluralRules.select(son)— kategoriya (one,few,many,other...), so'z emas; so'zni lug'atdan olasiz vaotherni unutmaysiz.- Kategoriyalar soni tilga bog'liq: xitoy — 1, o'zbek va ingliz — 2, rus — 4, arab — 6;
type: "ordinal"—1st,22nd. ListFormat—osh, manti va lag'mon;type:conjunction(va),disjunction(yoki),unit; faqat satrlar.DisplayNames— kod → nom (region,language,currency,script...);typemajburiy,fallback: "none".- Chrome 154:
PluralRules— bir xil;ListFormat— o'zbekcha yo'q va buni aytadi;DisplayNames— "bor" deydi, lekin inglizcha nom beradi.
Keyingi dars: Intl.Collator va Intl.Segmenter — o'zbek alifbosi bo'yicha saralash (o', g', sh, ch qayerda turadi?) va matnni so'z hamda gaplarga to'g'ri bo'lishni ko'ramiz.
Manbalar
- MDN: "Intl.PluralRules", "Intl.ListFormat", "Intl.DisplayNames" — developer.mozilla.org
- Unicode CLDR: "Language Plural Rules" jadvali — cldr.unicode.org
- ECMA-402, "PluralRules", "ListFormat", "DisplayNames" — tc39.es/ecma402
- web-features 3.40:
intl-plural-rules— Baseline 2019-sentabr;intl-list-format,intl-display-names— Baseline 2021-aprel
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!