كيف يمكنني تنسيق القوائم مثل أ، ب، و ج في جافا سكريبت؟

استخدم Intl.ListFormat لتنسيق المصفوفات بأدوات الربط والفواصل الخاصة باللغة المحلية.

مقدمة

عند عرض قائمة من العناصر للمستخدمين، تحتاج إلى ربطها بفواصل وأداة ربط مثل "و". تمتلك اللغات المختلفة اصطلاحات مختلفة لتنسيق القوائم. تستخدم اللغة الإنجليزية الفواصل و"and"، وتستخدم الإسبانية "y"، وتستخدم الفرنسية "et"، بينما تستخدم الصينية علامات ترقيم مختلفة تماماً.

تقوم واجهة برمجة التطبيقات Intl.ListFormat بتنسيق المصفوفات إلى سلاسل نصية مناسبة للغة المحلية مع الفواصل وأدوات الربط الصحيحة. وهذا يتعامل مع الاختلافات الثقافية في تنسيق القوائم بشكل تلقائي.

مشكلة التنسيق اليدوي للقوائم

يمكنك ربط عناصر المصفوفة بفواصل باستخدام طريقة join().

const fruits = ["apples", "oranges", "bananas"];
const list = fruits.join(", ");
console.log(list);
// "apples, oranges, bananas"

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

يمكنك إضافة "and" يدوياً قبل العنصر الأخير.

const fruits = ["apples", "oranges", "bananas"];
const lastFruit = fruits[fruits.length - 1];
const otherFruits = fruits.slice(0, -1);
const list = otherFruits.join(", ") + ", and " + lastFruit;
console.log(list);
// "apples, oranges, and bananas"

هذا الكود يعمل فقط للغة الإنجليزية. سيرى المستخدمون الناطقون بالإسبانية "apples, oranges, and bananas" بدلاً من "apples, oranges y bananas". وسيرى المستخدمون الناطقون بالفرنسية "and" بدلاً من "et". تختلف قواعد علامات الترقيم وأدوات الربط حسب اللغة.

استخدام Intl.ListFormat لتنسيق القوائم

يقوم منشئ Intl.ListFormat بإنشاء منسق يحول المصفوفات إلى سلاسل قوائم مناسبة للغة المحلية.

const formatter = new Intl.ListFormat("en");
const fruits = ["apples", "oranges", "bananas"];
console.log(formatter.format(fruits));
// "apples, oranges, and bananas"

يستخدم المنسق الفواصل وأداة الربط الصحيحة للغة المحددة. تقوم بتمرير اللغة المحلية كوسيط أول إلى المنشئ.

const enFormatter = new Intl.ListFormat("en");
const esFormatter = new Intl.ListFormat("es");
const frFormatter = new Intl.ListFormat("fr");

const fruits = ["apples", "oranges", "bananas"];

console.log(enFormatter.format(fruits));
// "apples, oranges, and bananas"

console.log(esFormatter.format(fruits));
// "apples, oranges y bananas"

console.log(frFormatter.format(fruits));
// "apples, oranges et bananas"

يطبق المنسق تلقائياً قواعد علامات الترقيم وأدوات الربط لكل لغة محلية.

تنسيق القوائم باستخدام "و"

السلوك الافتراضي لـ Intl.ListFormat يستخدم أداة العطف "و" أو ما يعادلها في اللغات الأخرى. وهذا ما يسمى بتنسيق العطف.

const formatter = new Intl.ListFormat("en", { type: "conjunction" });
const items = ["bread", "milk", "eggs"];
console.log(formatter.format(items));
// "bread, milk, and eggs"

خيار type يتحكم في نوع الرابط الذي يظهر بين العناصر. القيمة "conjunction" تنتج قوائم تستخدم "و". هذه هي القيمة الافتراضية، لذا يمكنك حذفها.

فهم خيارات نوع القائمة

يقبل خيار type ثلاث قيم تتحكم في كيفية ربط العناصر.

النوع "conjunction" يستخدم "و" أو ما يعادلها.

const formatter = new Intl.ListFormat("en", { type: "conjunction" });
console.log(formatter.format(["red", "green", "blue"]));
// "red, green, and blue"

النوع "disjunction" يستخدم "أو" أو ما يعادلها.

const formatter = new Intl.ListFormat("en", { type: "disjunction" });
console.log(formatter.format(["red", "green", "blue"]));
// "red, green, or blue"

النوع "unit" ينسق قوائم القياسات أو الكميات بدون أداة عطف.

const formatter = new Intl.ListFormat("en", { type: "unit" });
console.log(formatter.format(["5 pounds", "12 ounces"]));
// "5 pounds, 12 ounces"

نوع الوحدة يستخدم علامات ترقيم بسيطة مناسبة للبيانات التقنية أو بيانات القياس.

فهم خيارات النمط

خيار style يتحكم في طول ورسمية المخرجات المنسقة. يقبل ثلاث قيم.

النمط "long" يستخدم كلمات كاملة وعلامات ترقيم قياسية. هذا هو الافتراضي.

const formatter = new Intl.ListFormat("en", { style: "long" });
console.log(formatter.format(["Alice", "Bob", "Carol"]));
// "Alice, Bob, and Carol"

النمط "short" يستخدم أشكالًا مختصرة عندما تكون متاحة.

const formatter = new Intl.ListFormat("en", { style: "short" });
console.log(formatter.format(["Alice", "Bob", "Carol"]));
// "Alice, Bob, & Carol"

النمط "narrow" يستخدم أكثر الأشكال اختصارًا الممكنة.

const formatter = new Intl.ListFormat("en", { style: "narrow" });
console.log(formatter.format(["Alice", "Bob", "Carol"]));
// "Alice, Bob, Carol"

النمط الضيق غالبًا ما يحذف أداة العطف تمامًا. المخرجات الدقيقة تعتمد على اللغة المحلية.

كيف تقوم اللغات المختلفة بتنسيق القوائم

لكل لغة قواعدها الخاصة لتنسيق القوائم. يطبق المنسق هذه القواعد تلقائيًا.

تستخدم اللغة الإنجليزية الفواصل وتشمل فاصلة أكسفورد قبل "and".

const formatter = new Intl.ListFormat("en");
console.log(formatter.format(["coffee", "tea", "juice"]));
// "coffee, tea, and juice"

تستخدم اللغة الإسبانية الفواصل وأداة الربط "y".

const formatter = new Intl.ListFormat("es");
console.log(formatter.format(["café", "té", "jugo"]));
// "café, té y jugo"

تستخدم اللغة الفرنسية الفواصل وأداة الربط "et".

const formatter = new Intl.ListFormat("fr");
console.log(formatter.format(["café", "thé", "jus"]));
// "café, thé et jus"

تستخدم اللغة الصينية الحرف 和 بمعنى "و" وفاصلة التعداد 、 كفاصل.

const formatter = new Intl.ListFormat("zh");
console.log(formatter.format(["咖啡", "茶", "可乐"]));
// "咖啡、茶和可乐"

تستخدم اللغة الألمانية الفواصل وأداة الربط "und".

const formatter = new Intl.ListFormat("de");
console.log(formatter.format(["Kaffee", "Tee", "Saft"]));
// "Kaffee, Tee und Saft"

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

الحصول على الأجزاء الفردية باستخدام formatToParts

تُرجع طريقة formatToParts() مصفوفة من الكائنات تمثل كل جزء من القائمة المنسقة. هذا مفيد عندما تحتاج إلى تنسيق أجزاء مختلفة بشكل منفصل.

const formatter = new Intl.ListFormat("en");
const parts = formatter.formatToParts(["red", "green", "blue"]);
console.log(parts);

الناتج هو مصفوفة من الكائنات ذات خصائص type وvalue.

[
  { type: "element", value: "red" },
  { type: "literal", value: ", " },
  { type: "element", value: "green" },
  { type: "literal", value: ", and " },
  { type: "element", value: "blue" }
]

كل عنصر في القائمة له نوع "element". الفواصل وأدوات الربط لها نوع "literal". يمكنك استخدام هذا لتطبيق تنسيق مخصص.

const formatter = new Intl.ListFormat("en");
const parts = formatter.formatToParts(["red", "green", "blue"]);

const html = parts
  .map((part) => {
    if (part.type === "element") {
      return `<strong>${part.value}</strong>`;
    }
    return part.value;
  })
  .join("");

console.log(html);
// "<strong>red</strong>, <strong>green</strong>, and <strong>blue</strong>"

يمنحك هذا النهج تحكمًا دقيقًا في التنسيق مع الحفاظ على الفواصل وأدوات الربط المناسبة للغة.

دعم المتصفح

واجهة برمجة التطبيقات Intl.ListFormat متوفرة في جميع المتصفحات الحديثة. وهي مدعومة منذ أبريل 2021 في المتصفحات الرئيسية بما في ذلك Chrome وFirefox وSafari وEdge.

يمكنك التحقق مما إذا كانت واجهة برمجة التطبيقات متاحة قبل استخدامها.

if (typeof Intl.ListFormat !== "undefined") {
  const formatter = new Intl.ListFormat("en");
  console.log(formatter.format(["a", "b", "c"]));
} else {
  console.log("Intl.ListFormat is not supported");
}

بالنسبة للمتصفحات القديمة، تحتاج إلى توفير حل بديل أو استخدام polyfill. يمكن للحل البديل استخدام طريقة join() البسيطة.

function formatList(items, locale) {
  if (typeof Intl.ListFormat !== "undefined") {
    const formatter = new Intl.ListFormat(locale);
    return formatter.format(items);
  }
  return items.join(", ");
}

console.log(formatList(["red", "green", "blue"], "en"));
// "red, green, and blue" (أو "red, green, blue" في المتصفحات القديمة)

هذا يضمن عمل الكود الخاص بك حتى في المتصفحات التي لا تدعم Intl.ListFormat.