كيفية التحكم في ترتيب الأحرف الكبيرة أو الصغيرة أولاً في الفرز

استخدم خيار caseFirst في Intl.Collator لتحديد ترتيب حالة الأحرف عند فرز السلاسل النصية

مقدمة

عندما تقوم بفرز مصفوفة من السلاسل النصية التي تختلف فقط في استخدام الأحرف الكبيرة والصغيرة، يحتاج JavaScript إلى تحديد أي إصدار يأتي أولاً. هل يجب أن يأتي apple قبل Apple، أم يجب أن يأتي Apple قبل apple؟ التطبيقات المختلفة لديها متطلبات مختلفة لهذا الترتيب.

بشكل افتراضي، يعتمد ترتيب الفرز للسلاسل النصية التي تختلف فقط في حالة الأحرف على إعدادات اللغة والحساسية. في كثير من الحالات، تُعامل السلاسل النصية مثل apple و Apple على أنها متساوية، مما يجعل ترتيبها غير متوقع. عندما يكون ترتيب حالة الأحرف مهماً لتطبيقك، فأنت بحاجة إلى تحكم صريح في ما إذا كانت الأحرف الكبيرة أو الصغيرة تُفرز أولاً.

توفر واجهة برمجة التطبيقات Intl.Collator خيار caseFirst الذي يحدد ترتيب حالة الأحرف. يمكنك تكوين أداة المقارنة لوضع الأحرف الكبيرة قبل الأحرف الصغيرة، أو الأحرف الصغيرة قبل الأحرف الكبيرة، أو استخدام السلوك الافتراضي للغة. يشرح هذا الدرس كيفية عمل خيار caseFirst، ومتى يكون له تأثير، وكيفية استخدامه في سيناريوهات الفرز العملية.

ما يفعله خيار caseFirst

يتحكم خيار caseFirst في ترتيب السلاسل النصية التي تختلف فقط في استخدام الأحرف الكبيرة والصغيرة. يقبل ثلاث قيم نصية: "upper"، أو "lower"، أو "false".

عند تعيينه إلى "upper"، تُفرز الأحرف الكبيرة قبل نظيراتها الصغيرة. تأتي السلسلة النصية Apple قبل apple.

عند التعيين إلى "lower"، يتم ترتيب الأحرف الصغيرة قبل نظيراتها الكبيرة. تأتي السلسلة النصية apple قبل Apple.

عند التعيين إلى "false" (القيمة النصية، وليس القيمة المنطقية)، يستخدم المرتب ترتيب الحالة الافتراضي للغة المحلية. هذا هو السلوك الافتراضي عندما لا تحدد الخيار.

يؤثر خيار caseFirst فقط على السلاسل النصية المتطابقة باستثناء الحالة. يتم ترتيب السلاسل النصية التي تختلف في أحرفها الأساسية وفقاً لقواعد الترتيب الأبجدي العادية بغض النظر عن هذا الإعداد.

كيفية عمل ترتيب الحالة الافتراضي

بدون تحديد خيار caseFirst، يستخدم المرتب السلوك الافتراضي الذي يعتمد على اللغة المحلية وإعدادات الحساسية.

const collator = new Intl.Collator('en-US');
const words = ['apple', 'Apple', 'APPLE'];

words.sort(collator.compare);

console.log(words);
// Output: ['apple', 'Apple', 'APPLE']

يعتمد ترتيب الإخراج على التطبيق واللغة المحلية. مع إعدادات الحساسية الافتراضية، يأخذ المرتب في الاعتبار اختلافات الحالة، لكن الترتيب المحدد لـ apple وApple وAPPLE يختلف.

تحتوي اللغات المحلية المختلفة على اصطلاحات ترتيب حالة افتراضية مختلفة. تضع بعض اللغات المحلية تقليدياً الأحرف الصغيرة أولاً، بينما تضع لغات أخرى الأحرف الكبيرة أولاً. يؤدي الاعتماد على السلوك الافتراضي إلى نتائج غير متسقة عبر بيئات مختلفة.

وضع الأحرف الكبيرة أولاً باستخدام caseFirst upper

يضمن تعيين caseFirst: "upper" أن تأتي الأحرف الكبيرة دائماً قبل نظيراتها الصغيرة في النتائج المرتبة.

const collator = new Intl.Collator('en-US', { caseFirst: 'upper' });
const words = ['apple', 'Apple', 'banana', 'Banana'];

words.sort(collator.compare);

console.log(words);
// Output: ['Apple', 'apple', 'Banana', 'banana']

يقوم المرتب بالترتيب أبجدياً حسب الحرف الأساسي أولاً، ثم يطبق ترتيب الحالة داخل كل مجموعة. من بين الكلمات التي تبدأ بـ a، تأتي Apple قبل apple. من بين الكلمات التي تبدأ بـ b، تأتي Banana قبل banana.

هذا الترتيب مفيد عند عرض القوائم حيث يجب أن تظهر الأسماء العلمية أو العناوين بأحرف كبيرة بشكل بارز قبل الأسماء الشائعة.

const collator = new Intl.Collator('en-US', { caseFirst: 'upper' });
const names = ['smith', 'Smith', 'jones', 'Jones'];

names.sort(collator.compare);

console.log(names);
// Output: ['Jones', 'jones', 'Smith', 'smith']

تظهر الأسماء بأحرف كبيرة قبل الإصدارات بأحرف صغيرة، مما يسهل التمييز بين الأسماء العلمية والكلمات الشائعة في القوائم المختلطة.

وضع الأحرف الصغيرة أولاً باستخدام caseFirst lower

يضمن تعيين caseFirst: "lower" أن تأتي الأحرف الصغيرة دائماً قبل نظيراتها بأحرف كبيرة في النتائج المرتبة.

const collator = new Intl.Collator('en-US', { caseFirst: 'lower' });
const words = ['apple', 'Apple', 'banana', 'Banana'];

words.sort(collator.compare);

console.log(words);
// Output: ['apple', 'Apple', 'banana', 'Banana']

يقوم المرتب بالترتيب أبجدياً أولاً، ثم يضع الإصدارات بأحرف صغيرة قبل الإصدارات بأحرف كبيرة ضمن كل مجموعة أبجدية.

يطابق هذا الترتيب الاتفاقيات حيث يُعتبر النص بأحرف صغيرة أكثر معيارية أو حيادية، مع الاحتفاظ بالأحرف الكبيرة للتأكيد أو الحالات الخاصة.

const collator = new Intl.Collator('en-US', { caseFirst: 'lower' });
const tags = ['javascript', 'JavaScript', 'python', 'Python'];

tags.sort(collator.compare);

console.log(tags);
// Output: ['javascript', 'JavaScript', 'python', 'Python']

تظهر العلامات بأحرف صغيرة أولاً، وهو أمر مفيد عندما تمثل الأحرف الصغيرة الشكل القياسي وتكون الإصدارات بأحرف كبيرة أقل شيوعاً.

استخدام caseFirst false لسلوك اللغة الافتراضي

يطلب تعيين caseFirst: "false" (قيمة السلسلة النصية) صراحةً ترتيب الأحرف الافتراضي للغة. ينتج هذا نفس النتيجة كحذف الخيار بالكامل.

const collator = new Intl.Collator('en-US', { caseFirst: 'false' });
const words = ['apple', 'Apple', 'APPLE'];

words.sort(collator.compare);

console.log(words);
// Output depends on locale implementation

يعتمد ترتيب الإخراج على ما تعتبره اللغة معياراً. تحدد بعض اللغات الأحرف الكبيرة أولاً، وتحدد أخرى الأحرف الصغيرة أولاً، وتعامل بعضها السلاسل النصية المختلفة في الأحرف على أنها متساوية.

هذا الخيار مفيد عندما تريد توضيح أنك تستخدم الإعدادات الافتراضية للغة بدلاً من حذف خيار التكوين عن طريق الخطأ.

متى لا يكون لـ caseFirst تأثير

يؤثر خيار caseFirst على المقارنة فقط عندما يسمح إعداد الحساسية بأهمية اختلافات الأحرف. مع sensitivity: "base" أو sensitivity: "accent"، يتم تجاهل اختلافات الأحرف بالكامل، مما يجعل خيار caseFirst غير ذي صلة.

const collator = new Intl.Collator('en-US', {
  sensitivity: 'base',
  caseFirst: 'upper'
});

const words = ['apple', 'Apple', 'APPLE'];

words.sort(collator.compare);

console.log(words);
// Output: ['apple', 'Apple', 'APPLE'] (or any order)

مع الحساسية الأساسية، يتعامل المُرتِّب مع السلاسل النصية الثلاثة على أنها متساوية. خيار caseFirst ليس له تأثير لأن حالة الأحرف لا تُؤخذ في الاعتبار على الإطلاق. تحافظ خوارزمية الترتيب على الترتيب الأصلي للعناصر المتساوية (ترتيب مستقر)، لذا يطابق الناتج ترتيب الإدخال.

لكي يكون لـ caseFirst تأثير، استخدم sensitivity: "case" أو sensitivity: "variant" (الافتراضي).

const collator = new Intl.Collator('en-US', {
  sensitivity: 'variant',
  caseFirst: 'upper'
});

const words = ['apple', 'Apple', 'APPLE'];

words.sort(collator.compare);

console.log(words);
// Output: ['APPLE', 'Apple', 'apple']

مع حساسية المتغيرات (التي تأخذ في الاعتبار جميع الاختلافات بما في ذلك حالة الأحرف)، يحدد خيار caseFirst ترتيب هذه السلاسل النصية المختلفة في حالة الأحرف.

ترتيب الأسماء مع ترتيب متسق لحالة الأحرف

عند ترتيب أسماء المستخدمين أو الأسماء العلم الأخرى، يضمن الترتيب المتسق لحالة الأحرف نتائج يمكن التنبؤ بها عبر تطبيقك.

const collator = new Intl.Collator('en-US', { caseFirst: 'upper' });

const users = [
  { name: 'alice' },
  { name: 'Alice' },
  { name: 'bob' },
  { name: 'Bob' }
];

users.sort((a, b) => collator.compare(a.name, b.name));

users.forEach(user => {
  console.log(user.name);
});
// Output:
// Alice
// alice
// Bob
// bob

يضع المُرتِّب الأسماء المكتوبة بأحرف كبيرة قبل الإصدارات المكتوبة بأحرف صغيرة. يسهل هذا الترتيب رؤية الأسماء العلم مقابل الكلمات الشائعة في مجموعات البيانات المختلطة.

ترتيب أسماء الملفات مع ترتيب محكوم لحالة الأحرف

تتمتع أنظمة الملفات بسلوكيات مختلفة لحساسية حالة الأحرف. يتعامل بعضها مع الأحرف الكبيرة والصغيرة على أنها متماثلة، بينما يتعامل البعض الآخر معها على أنها مختلفة. يضمن الترتيب الصريح لحالة الأحرف أن قوائم الملفات المرتبة تطابق توقعات المستخدم بغض النظر عن نظام الملفات الأساسي.

const collator = new Intl.Collator('en-US', { caseFirst: 'lower' });

const files = ['README.md', 'readme.md', 'index.js', 'Index.js'];

files.sort(collator.compare);

console.log(files);
// Output: ['index.js', 'Index.js', 'readme.md', 'README.md']

تظهر الإصدارات المكتوبة بأحرف صغيرة أولاً، مما يطابق الاصطلاح حيث تكون أسماء الملفات المكتوبة بأحرف صغيرة أكثر شيوعاً على الأنظمة الشبيهة بـ Unix.

دمج caseFirst مع الترتيب الرقمي

يعمل خيار caseFirst جنباً إلى جنب مع خيارات الترتيب الأخرى مثل numeric. يمكنك ترتيب السلاسل النصية التي تحتوي على أرقام مضمنة مع التحكم في ترتيب حالة الأحرف.

const collator = new Intl.Collator('en-US', {
  numeric: true,
  caseFirst: 'upper'
});

const items = ['item1', 'Item1', 'item2', 'Item2', 'item10', 'Item10'];

items.sort(collator.compare);

console.log(items);
// Output: ['Item1', 'item1', 'Item2', 'item2', 'Item10', 'item10']

يطبق المُرتِّب المقارنة الرقمية لأجزاء الأرقام وترتيب حالة الأحرف لأجزاء الحروف. يتم ترتيب العناصر حسب القيمة الرقمية أولاً (1، 2، 10)، ثم حسب حالة الأحرف ضمن كل مجموعة رقمية.

استخدام مفتاح امتداد Unicode لـ caseFirst

يمكن أيضًا تعيين خيار caseFirst من خلال امتداد Unicode في معرّف اللغة باستخدام مفتاح kf. قيم الامتداد هي upper وlower وfalse.

const collator = new Intl.Collator('en-US-u-kf-upper');
const words = ['apple', 'Apple', 'banana', 'Banana'];

words.sort(collator.compare);

console.log(words);
// Output: ['Apple', 'apple', 'Banana', 'banana']

سلسلة اللغة en-US-u-kf-upper تحدد الإنجليزية الأمريكية مع ترتيب الأحرف الكبيرة أولاً. ينتج هذا نفس النتيجة التي يتم الحصول عليها عند تمرير { caseFirst: 'upper' } في كائن الخيارات.

عندما يحدد كل من امتداد Unicode وكائن الخيارات caseFirst، يكون لكائن الخيارات الأولوية.

const collator = new Intl.Collator('en-US-u-kf-upper', {
  caseFirst: 'lower'
});

const words = ['apple', 'Apple'];

words.sort(collator.compare);

console.log(words);
// Output: ['apple', 'Apple']

يحدد كائن الخيارات caseFirst: 'lower'، والذي يتجاوز امتداد kf-upper في سلسلة اللغة. يستخدم المرتب ترتيب الأحرف الصغيرة أولاً.

التحقق من قيمة caseFirst التي يستخدمها المرتب

تُرجع طريقة resolvedOptions() الخيارات الفعلية التي يستخدمها المرتب، بما في ذلك إعداد caseFirst.

const collator = new Intl.Collator('en-US', { caseFirst: 'upper' });
const options = collator.resolvedOptions();

console.log(options.caseFirst);
// Output: "upper"

هذا مفيد لتصحيح الأخطاء أو التحقق من أن المرتب لديه التكوين المتوقع، خاصة عند دمج امتدادات Unicode مع كائنات الخيارات.

const collator = new Intl.Collator('en-US-u-kf-lower');
const options = collator.resolvedOptions();

console.log(options.caseFirst);
// Output: "lower"

تعكس الخيارات المحلولة إعداد امتداد Unicode عندما لا يتجاوزه أي كائن خيارات.

متى تستخدم كل قيمة من قيم caseFirst

استخدم caseFirst: "upper" عندما:

  • تريد أن تظهر الأسماء العلمية أو العناوين قبل الكلمات الشائعة
  • تعامل اتفاقية تطبيقك النص بأحرف كبيرة على أنه أكثر أهمية
  • تقوم بترتيب الأسماء حيث تكون الإصدارات بأحرف كبيرة هي المعيارية

استخدم caseFirst: "lower" عندما:

  • تريد أن يظهر النص بأحرف صغيرة أولاً كشكل قياسي
  • تعامل اتفاقية تطبيقك الأحرف الصغيرة كإعداد افتراضي والأحرف الكبيرة كحالة خاصة
  • تقوم بترتيب المعرّفات التقنية حيث تكون الأحرف الصغيرة أكثر شيوعًا

استخدم caseFirst: "false" عندما:

  • تريد اتباع الاصطلاحات الخاصة بالمنطقة
  • لا يهم ترتيب السلاسل النصية ذات الأحرف المختلفة في التطبيق الخاص بك
  • تريد توضيح أنك تستخدم الإعدادات الافتراضية بدلاً من حذف الخيار عن طريق الخطأ