كيفية تنسيق النطاقات مثل 3-5 أو 100-200
استخدام جافا سكريبت لعرض نطاقات الأرقام بتنسيق مناسب للغة المحلية
مقدمة
تظهر نطاقات الأرقام في جميع أنحاء واجهات المستخدم. تظهر نطاقات الأسعار على شكل $100-$200، وأرقام الصفحات على شكل 1-10، وتقديرات الكمية على شكل 3-5 عناصر. توصل هذه النطاقات أن القيمة تقع بين نقطتي نهاية، مما يوفر للمستخدمين معلومات محددة بدلاً من رقم دقيق واحد.
عندما تقوم بتثبيت الفاصل بين قيم النطاق، فإنك تفترض أن جميع المستخدمين يتبعون نفس الاصطلاحات الطباعية. عادة ما يستخدم المتحدثون باللغة الإنجليزية الواصلات أو الشرطات للنطاقات، ولكن اللغات الأخرى تستخدم رموزًا أو كلمات مختلفة. تستخدم الألمانية "bis" بين الأرقام، بينما تضع بعض اللغات مسافات حول الفواصل.
توفر جافا سكريبت طريقة formatRange() على Intl.NumberFormat للتعامل مع تنسيق النطاق تلقائيًا. تطبق هذه الطريقة الاصطلاحات الخاصة باللغة المحلية على كل من الأرقام والفاصل، مما يضمن عرض النطاقات بشكل صحيح للمستخدمين في جميع أنحاء العالم.
لماذا تحتاج نطاقات الأرقام إلى تنسيق خاص باللغة المحلية
طورت الثقافات المختلفة اصطلاحات مختلفة للتعبير عن النطاقات. تتضمن هذه الاصطلاحات كلاً من رمز الفاصل والمسافة حوله.
في اللغة الإنجليزية الأمريكية، تستخدم النطاقات عادةً شرطة بدون مسافات: 3-5، 100-200. في بعض أدلة الأسلوب، تظهر المسافات حول الشرطة: 3 - 5. يختلف الاصطلاح الدقيق حسب السياق ومعايير النشر.
في الألمانية، غالبًا ما تستخدم النطاقات "bis" كفاصل: 3 bis 5، 100 bis 200. يجعل هذا النهج القائم على الكلمات علاقة النطاق صريحة بدلاً من الاعتماد على علامات الترقيم.
في الإسبانية، يمكن أن تستخدم النطاقات شرطة مثل الإنجليزية أو كلمة "a": 3-5 أو 3 a 5. يعتمد الاختيار على المنطقة الناطقة بالإسبانية المحددة والسياق.
عند تنسيق النطاقات التي تتضمن العملة أو الوحدات، تزداد التعقيدات. قد يظهر نطاق السعر كـ $100-$200 في اللغة الإنجليزية الأمريكية، ولكن كـ 100 €-200 € في الألمانية، أو 100-200 € مع ظهور رمز العملة مرة واحدة فقط. تضع اللغات المحلية المختلفة رموز العملة بشكل مختلف وتتعامل مع التكرار بشكل مختلف.
يتطلب تنسيق النطاق اليدوي معرفة هذه الاصطلاحات وتنفيذ المنطق الخاص باللغة المحلية. تغلف واجهة برمجة التطبيقات Intl هذه المعرفة، وتطبق التنسيق المناسب بناءً على اللغة المحلية.
استخدام formatRange لتنسيق نطاقات الأرقام
تقبل طريقة formatRange() رقمين وتعيد سلسلة نصية منسقة تمثل النطاق. قم بإنشاء كائن Intl.NumberFormat باللغة والخيارات المطلوبة، ثم استدعِ formatRange() مع قيم البداية والنهاية.
const formatter = new Intl.NumberFormat("en-US");
console.log(formatter.formatRange(3, 5));
// الناتج: "3–5"
console.log(formatter.formatRange(100, 200));
// الناتج: "100–200"
console.log(formatter.formatRange(1000, 5000));
// الناتج: "1,000–5,000"
يطبق المنسق فواصل الآلاف على كلا الرقمين في النطاق ويستخدم فاصلاً مناسباً بينهما. بالنسبة للإنجليزية الأمريكية، يكون هذا شرطة متوسطة بدون مسافات.
يمكنك تنسيق نفس النطاق للغات مختلفة عن طريق تغيير معرف اللغة.
const usFormatter = new Intl.NumberFormat("en-US");
console.log(usFormatter.formatRange(100, 200));
// الناتج: "100–200"
const deFormatter = new Intl.NumberFormat("de-DE");
console.log(deFormatter.formatRange(100, 200));
// الناتج: "100–200"
const esFormatter = new Intl.NumberFormat("es-ES");
console.log(esFormatter.formatRange(100, 200));
// الناتج: "100-200"
تطبق كل لغة اتفاقياتها الخاصة للفاصل والتباعد. تتعامل واجهة البرمجة مع هذه التفاصيل تلقائياً بناءً على المعايير الطباعية للغة.
تنسيق نطاقات العملات
يعمل تنسيق النطاق مع أي خيارات تنسيق الأرقام، بما في ذلك العملة. عند تنسيق نطاقات العملة، يتعامل المنسق مع وضع رمز العملة وفاصل النطاق.
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
console.log(formatter.formatRange(100, 200));
// الناتج: "$100 – $200"
console.log(formatter.formatRange(1000, 5000));
// الناتج: "$1,000 – $5,000"
يضع المنسق رمز العملة قبل كل رقم في النطاق. هذا يوضح أن كلا القيمتين تمثلان مبالغ بالعملة.
تضع اللغات المختلفة رموز العملة بطرق مختلفة.
const usFormatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
console.log(usFormatter.formatRange(100, 200));
// الناتج: "$100 – $200"
const deFormatter = new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR",
maximumFractionDigits: 0
});
console.log(deFormatter.formatRange(100, 200));
// الناتج: "100–200 €"
يضع المنسق الألماني رمز اليورو بعد النطاق بدلاً من وضعه قبل كل رقم. وهذا يتبع الاتفاقيات الطباعية الألمانية لنطاقات العملة.
ماذا يحدث عندما تكون قيم النطاق متساوية تقريبًا
عندما تُقرّب قيم البداية والنهاية إلى نفس الرقم بعد التنسيق، يقوم المنسق بطي النطاق وقد يضيف رمز التقريب.
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
console.log(formatter.formatRange(100, 200));
// Output: "$100 – $200"
console.log(formatter.formatRange(100, 120));
// Output: "$100 – $120"
console.log(formatter.formatRange(100.2, 100.8));
// Output: "~$100"
يوضح المثال الثالث قيمتين تُقربان إلى نفس العدد الصحيح. بدلاً من عرض "$100 – $100"، والتي لا تنقل أي معلومات عن النطاق، يُخرج المنسق "~$100". يشير رمز التلدة إلى أن القيمة تقريبية.
ينطبق هذا السلوك عندما تتسبب خيارات التنسيق في ظهور قيم البداية والنهاية متطابقة.
const formatter = new Intl.NumberFormat("en-US", {
maximumFractionDigits: 1
});
console.log(formatter.formatRange(2.9, 3.1));
// Output: "~3"
console.log(formatter.formatRange(2.94, 2.96));
// Output: "~2.9"
يُدرج المنسق رمز التقريب فقط عند الحاجة. عندما تُقرب القيم إلى أرقام مختلفة، يعرضها كنطاق قياسي.
تنسيق النطاقات مع المنازل العشرية
يحافظ تنسيق النطاق على إعدادات المنازل العشرية من خيارات المنسق. يمكنك التحكم في الدقة لكلتا القيمتين في النطاق.
const formatter = new Intl.NumberFormat("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
console.log(formatter.formatRange(3.5, 5.7));
// Output: "3.50–5.70"
console.log(formatter.formatRange(100, 200));
// Output: "100.00–200.00"
يطبق المنسق إعدادات المنازل العشرية على كلا الرقمين في النطاق. هذا يضمن دقة متسقة عبر عرض النطاق بأكمله.
يمكنك الجمع بين تنسيق الأرقام العشرية مع العملات أو الأنماط الأخرى.
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
console.log(formatter.formatRange(99.99, 199.99));
// Output: "$99.99 – $199.99"
تنسيق نطاقات الأرقام في لغات مختلفة
يتكيف تنسيق النطاق مع اصطلاحات كل لغة محلية للأرقام والفواصل والمسافات.
const enFormatter = new Intl.NumberFormat("en-US");
console.log(enFormatter.formatRange(1000, 5000));
// Output: "1,000–5,000"
const deFormatter = new Intl.NumberFormat("de-DE");
console.log(deFormatter.formatRange(1000, 5000));
// Output: "1.000–5.000"
const frFormatter = new Intl.NumberFormat("fr-FR");
console.log(frFormatter.formatRange(1000, 5000));
// Output: "1 000–5 000"
const jaFormatter = new Intl.NumberFormat("ja-JP");
console.log(jaFormatter.formatRange(1000, 5000));
// Output: "1,000~5,000"
تستخدم اللغة الإنجليزية الفواصل لفصل الآلاف وشرطة متوسطة للنطاق. تستخدم الألمانية النقاط للآلاف وشرطة متوسطة. تستخدم الفرنسية المسافات للآلاف وشرطة متوسطة. تستخدم اليابانية الفواصل للآلاف وشرطة متموجة (~) للنطاق.
تمتد هذه الاختلافات إلى تنسيق العملات.
const enFormatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD"
});
console.log(enFormatter.formatRange(100, 200));
// Output: "$100.00 – $200.00"
const deFormatter = new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR"
});
console.log(deFormatter.formatRange(100, 200));
// Output: "100,00–200,00 €"
const jaFormatter = new Intl.NumberFormat("ja-JP", {
style: "currency",
currency: "JPY"
});
console.log(jaFormatter.formatRange(100, 200));
// Output: "¥100~¥200"
تطبق كل لغة محلية قواعدها الخاصة لوضع رمز العملة، وفواصل العشرية، وفواصل النطاق. تتعامل واجهة البرمجة مع جميع هذه الاختلافات تلقائيًا.
دمج formatRange مع التدوين المضغوط
يعمل تنسيق النطاق مع التدوين المضغوط، مما يتيح لك عرض نطاقات مثل 1K-5K أو 1M-5M.
const formatter = new Intl.NumberFormat("en-US", {
notation: "compact"
});
console.log(formatter.formatRange(1000, 5000));
// Output: "1K–5K"
console.log(formatter.formatRange(1000000, 5000000));
// Output: "1M–5M"
console.log(formatter.formatRange(1200, 4800));
// Output: "1.2K–4.8K"
يطبق المنسق التدوين المضغوط على كلا القيمتين في النطاق. هذا يبقي المخرجات موجزة مع نقل معلومات النطاق.
عندما يمتد النطاق عبر مستويات حجم مختلفة، يتعامل المنسق مع كل قيمة بشكل مناسب.
const formatter = new Intl.NumberFormat("en-US", {
notation: "compact"
});
console.log(formatter.formatRange(500, 1500));
// Output: "500–1.5K"
console.log(formatter.formatRange(900000, 1200000));
// Output: "900K–1.2M"
قد لا تستخدم قيمة البداية التدوين المضغوط بينما تستخدمه قيمة النهاية، أو قد تستخدم مؤشرات حجم مختلفة. يتخذ المنسق هذه القرارات بناءً على حجم كل قيمة.
استخدام formatRangeToParts للتنسيق المخصص
تُرجع طريقة formatRangeToParts() مصفوفة من الكائنات التي تمثل أجزاء النطاق المنسق. هذا يسمح لك بتنسيق أو معالجة المكونات الفردية للنطاق.
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
const parts = formatter.formatRangeToParts(100, 200);
console.log(parts);
الناتج هو مصفوفة من الكائنات، كل منها يحتوي على خصائص type وvalue وsource.
[
{ type: "currency", value: "$", source: "startRange" },
{ type: "integer", value: "100", source: "startRange" },
{ type: "literal", value: " – ", source: "shared" },
{ type: "currency", value: "$", source: "endRange" },
{ type: "integer", value: "200", source: "endRange" }
]
تحدد خاصية type ما يمثله الجزء: رمز العملة، أو العدد الصحيح، أو فاصل العشري، أو النص الحرفي. تحتوي خاصية value على النص المنسق. تشير خاصية source إلى ما إذا كان الجزء ينتمي إلى القيمة البدائية، أو القيمة النهائية، أو مشترك بينهما.
يمكنك استخدام هذه الأجزاء لإنشاء HTML مخصص بأنماط مختلفة للمكونات المختلفة.
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
const parts = formatter.formatRangeToParts(100, 200);
let html = "";
parts.forEach(part => {
if (part.type === "currency") {
html += `<span class="currency-symbol">${part.value}</span>`;
} else if (part.type === "integer") {
html += `<span class="amount">${part.value}</span>`;
} else if (part.type === "literal") {
html += `<span class="separator">${part.value}</span>`;
} else {
html += part.value;
}
});
console.log(html);
// الناتج: <span class="currency-symbol">$</span><span class="amount">100</span><span class="separator"> – </span><span class="currency-symbol">$</span><span class="amount">200</span>
تتيح لك هذه التقنية تطبيق فئات CSS، وإضافة تلميحات، أو تنفيذ سلوكيات مخصصة أخرى مع الحفاظ على التنسيق الصحيح الخاص باللغة.
التعامل مع الحالات الحدية مع formatRange
تتضمن طريقة formatRange() معالجة الأخطاء للمدخلات غير الصالحة. إذا كانت أي من المعاملات undefined، يتم إلقاء TypeError. إذا كانت أي من المعاملات NaN أو لا يمكن تحويلها إلى رقم، يتم إلقاء RangeError.
const formatter = new Intl.NumberFormat("en-US");
try {
console.log(formatter.formatRange(100, undefined));
} catch (error) {
console.log(error.name);
// Output: "TypeError"
}
try {
console.log(formatter.formatRange(NaN, 200));
} catch (error) {
console.log(error.name);
// Output: "RangeError"
}
عند العمل مع مدخلات المستخدم أو البيانات من مصادر خارجية، تحقق من أن القيم هي أرقام صالحة قبل تمريرها إلى formatRange().
تقبل الطريقة الأرقام، قيم BigInt، أو السلاسل النصية التي تمثل أرقامًا صالحة.
const formatter = new Intl.NumberFormat("en-US");
console.log(formatter.formatRange(100, 200));
// Output: "100–200"
console.log(formatter.formatRange(100n, 200n));
// Output: "100–200"
console.log(formatter.formatRange("100", "200"));
// Output: "100–200"
يتم تحليل المدخلات النصية كأرقام، مع الحفاظ على الدقة دون مشاكل تحويل الفاصلة العائمة.
متى تستخدم formatRange مقابل التنسيق اليدوي
استخدم formatRange() عند عرض النطاقات للمستخدمين. ينطبق هذا على نطاقات الأسعار، نطاقات الكميات، نطاقات القياس، أرقام الصفحات، أو أي قيم محدودة أخرى. تضمن الطريقة التنسيق الصحيح الخاص باللغة المحلية دون الحاجة إلى تنفيذ منطق الفاصل بنفسك.
تجنب استخدام formatRange() عندما تحتاج إلى عرض قيم متعددة منفصلة غير مرتبطة دلاليًا كنطاق. على سبيل المثال، عرض قائمة أسعار مثل "$100، $150، $200" يجب أن يستخدم استدعاءات format() العادية لكل قيمة بدلاً من معاملتها كنطاقات.
تجنب أيضًا استخدام formatRange() عندما لا تكون العلاقة بين القيم نطاقًا رقميًا. إذا كنت تعرض مقارنة أو اختلافًا، استخدم التنسيق المناسب لذلك السياق بدلاً من تنسيق النطاق.