شیء Intl.Collator یک ابزار فوقالعاده کاربردی برای مقایسه و مرتبسازی رشتههای متنی (Strings) است. این ابزار دو رشته را به عنوان ورودی میگیرد و عددی را برمیگرداند که موقعیت و ترتیب آنها را نسبت به یکدیگر مشخص میکند؛ دقیقاً به همان روشی که آرگومان compareFn در متد معروف Array.prototype.sort() عمل میکند.
دلایل بسیار زیادی وجود دارد که نشان میدهد شما هرگز نباید از عملگرهای سنتی جاوااسکریپت مثل === یا < و > برای مقایسه متونی که کاربر آنها را میبیند استفاده کنید:
تفاوتهای نگارشی بیاهمیت: به عنوان مثال در زبان انگلیسی، کلمات "naïve" و "naive" صرفاً دو املای متفاوت از یک کلمه واحد هستند و در زمان جستجو یا مرتبسازی باید کاملاً مساوی در نظر گرفته شوند.
نادیده گرفتن بزرگی و کوچکی حروف (Case Insensitivity): در بیشتر مواقع هنگام مقایسه متون میخواهید بزرگی یا کوچکی حروف را نادیده بگیرید؛ مثلاً کلمات "apple" و "Apple" باید با هم برابر باشند.
بیمعنی بودن ترتیب بر اساس کدهای یونیکد (Code Point Order): عملگرهایی مثل < یا > رشتهها را بر اساس ردیفِ کدهای یونیکد آنها مقایسه میکنند که این ترتیب اصلاً با ترتیب الفبایی کلمات در یک لغتنامه واقعی همخوانی ندارد! به عنوان مثال، کاراکتر "ï" در جدول یونیکدها خیلی بعد از حرف "z" قرار دارد، اما در لغتنامه شما انتظار دارید این حرف دقیقاً در کنار حرف "i" قرار بگیرد.
نرمالسازی یونیکد (Unicode Normalization): یک کاراکتر واحد ممکن است به چندین روش مختلف در یونیکد بازنمایی و ذخیره شود. مثلاً حرف "ñ" میتواند به صورت یک کاراکتر مستقل ذخیره شود، یا به صورت یک حرف "n" معمولی که یک کاراکتر موجی (Tilde) به آن چسبیده است. این دو حالت در ظاهر یکی هستند اما کدهای متفاوتی دارند و باید مساوی درمان شوند.
مقایسه اعداد درون متن: اعدادی که داخل رشتههای متنی قرار دارند باید به عنوان «عدد» مقایسه شوند، نه به عنوان «متن». به عنوان مثال، شما قطعاً میخواهید عبارت "test-10" بعد از عبارت "test-2" قرار بگیرد (در حالی که در مقایسه متنیِ عادی، چون کاراکتر ۱ کوچکتر از ۲ است، برعکس میشود!).
ما دو سناریوی کاملاً مجزا برای تطبیق متون داریم: مرتبسازی (Sorting) و جستجو (Searching).
مرتبسازی زمانی است که شما لیستی از رشتهها را در اختیار دارید و میخواهید آنها را بر اساس یک قانون الفبایی منظم کنید.
جستجو زمانی است که یک لیست از متون دارید و میخواهید آیتمی را پیدا کنید که با عبارت درخواستی کاربر مطابقت دارد. در زمان جستجو، شما فقط باید به این توجه کنید که آیا نتیجه مقایسه صفر (برابر) است یا خیر؛ و علامت مثبت یا منفی بودن عدد بازگشتی دیگر برایتان اهمیتی ندارد.
نکته جالب اینجاست که حتی در یک زبان واحد، روشهای مرتبسازی متفاوتی وجود دارد. به عنوان مثال، در زبان آلمانی دو نوع ترتیب مرتبسازی کاملاً رسمی وجود دارد: روش دفترچه تلفنی (Phonebook) و روش لغتنامهای (Dictionary).
phonebk)در این روش، تمرکز اصلی روی «آوا و صدای کلمات» است؛ به طوری که قبل از انجام مرتبسازی، فرض میشود حروف صدادارِ نشانهدار مثل "ä" یا "ö" به معادلهای کشیدهی آنها یعنی "ae" یا "oe" تبدیل شدهاند:
const names = ["Hochberg", "Hönigswald", "Holzman"];
// ساخت یک Collator با پسوند تگ زبان آلمانی مخصوص دفترچه تلفن
const germanPhonebook = new Intl.Collator("de-DE-u-co-phonebk");
// مرتبسازی انجام میشود، انگار که داریم این لیست را مرتب میکنیم:
// ["Hochberg", "Hoenigswald", "Holzman"]
console.log(names.sort(germanPhonebook.compare));
// خروجی: ['Hochberg', 'Hönigswald', 'Holzman']
dict)برخی از کلمات آلمانی در زمان صرف شدن، نشانههای صوتی (Umlauts) اضافهای دریافت میکنند؛ بنابراین در لغتنامهها منطقیتر است که در زمان مرتبسازی، این نشانهها کاملاً نادیده گرفته شوند (مگر در شرایطی که دو کلمه دقیقاً کپی هم باشند و تفاوتشان فقط در همین نشانه باشد؛ مثل کلمه schon که قبل از schön قرار میگیرد):
// استفاده از همان لیست نامها اما با پسوند لغتنامهای آلمانی
const germanDictionary = new Intl.Collator("de-DE-u-co-dict");
// مرتبسازی انجام میشود، انگار که داریم این لیست را مرتب میکنیم:
// ["Hochberg", "Honigswald", "Holzman"]
console.log(names.sort(germanDictionary.compare).join(", "));
// خروجی: "Hochberg, Holzman, Hönigswald"
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://developer.mozilla.org/en-US/docs/Web/JavaScript