مرتب السطور وأداة إزالة التكرار

رتّب أسطر النص من الألف إلى الياء أو العكس، احذف الأسطر المكررة والفارغة، وأصلح الترتيب الرقمي الطبيعي بحيث يأتي item2 قبل item10 — كل ذلك فورًا داخل المتصفح.

223 مشاهدة

لماذا يُرتَّب "item10" قبل "item2" في الفرز الأبجدي البسيط

يقارن الفرز القياسي — من النوع الذي يقف خلف طريقة Array.sort() في JavaScript أو زر A→Z في جدول بيانات — سطرين حرفًا بحرف، من اليسار إلى اليمين، باستخدام نقطة الكود اليونيكود لكل حرف. إنه لا ينظر إلى سلسلة من الأرقام كرقم كامل؛ بل يسأل فقط أي حرف أصغر أو أكبر من الآخر، موضعًا واحدًا في كل مرة. لهذا السبب فإن قائمة تحتوي item1 وitem2 وitem9 وitem10 وitem20 تُرتَّب، حرفًا بحرف، على النحو التالي: item1، item10، item2، item20، item9: عند مقارنة "item10" و"item2" حرفًا بحرف، تكون السلسلتان متطابقتين حتى "item"، ثم يحدد الحرف التالي كل شيء — "1" مقابل "2". ولأن الحرف "1" أصغر من الحرف "2"، يُرتَّب item10 قبل item2، رغم أن عشرة أكبر رقميًا من اثنين. تعاني كل قائمة تظهر فيها أرقام داخل نص من هذه المشكلة: أرقام الإصدارات، أسماء الملفات مثل image2.jpg وimage10.jpg، أرقام الفواتير، والتعليمات المرقّمة خطوة بخطوة.

يحل الفرز الطبيعي — ويُسمى أيضًا الفرز الرقمي — هذه المشكلة عبر التعرف على سلسلة أرقام متتالية كرقم واحد ومقارنة قيمته بدلًا من مقارنة الأرقام حرفًا بحرف. يُفوِّض خيار الفرز الطبيعي في هذه الأداة هذا المنطق إلى واجهة برمجة Intl المدمجة في المتصفح، فيشغّل a.localeCompare(b, undefined, {numeric: true, sensitivity: "base"}) على كل زوج من الأسطر. تخبر راية numeric:true المقارنة باكتشاف سلاسل الأرقام ومعاملتها كأرقام، بحيث يستقر item2 بشكل صحيح قبل item10، وitem9 قبل item20 — وهو الترتيب الذي يتوقعه شخص يقرأ القائمة، لا الترتيب الذي تنتجه المقارنة حرفًا بحرف.

مقارنة واعية باللغة، لا مجرد رموز الأحرف

يعتمد الترتيب الأبجدي أيضًا على قواعد اللغة المطبَّقة، وهنا تفشل المقارنة البسيطة حتى دون وجود أرقام على الإطلاق. في الإنجليزية، "a" و"A" هما نفس الحرف بحالتين، والحروف المُشكَّلة مثل é تُرتَّب عادةً قريبة من e. أما التركية، فتعامل "ı" (الياء بلا نقطة) و"i" (الياء بنقطة) كحرفين منفصلين لهما موضعان مستقلان في الأبجدية — تمييز لا تستطيع مقارنة نقاط الكود الخام، التي تفحص فقط قيم يونيكود الرقمية، معرفته إطلاقًا. تأخذ localeCompare، وهي نفس طريقة Intl التي يعتمد عليها خيار الفرز الطبيعي، قواعد اللغة بعين الاعتبار: فمع sensitivity: "base" تعامل الفروق بين حالة الأحرف والتشكيل على أنها متكافئة لأغراض الترتيب، مع احترام الترتيب الحقيقي لحروف كل أبجدية سواء كانت إنجليزية أو تركية أو ألمانية أو لغة أخرى بحروف لاتينية.

تجمع هذه الأداة بين الاعتبارين في خطوة واحدة: اختر الترتيب الأبجدي A→Z أو Z→A كترتيب أساسي، أضف اختياريًا الفرز الرقمي الطبيعي فوقه بحيث تُقارَن الأرقام المضمَّنة بقيمتها لا برقمها، ثم احذف اختياريًا الأسطر المكررة والفارغة والمسافات البيضاء في البداية أو النهاية. ولأن اكتشاف التكرار يقارن الأسطر كسلاسل نصية دقيقة، فإن التشذيب (trimming) مهم: تبدو "apple" و"apple " (بمسافة زائدة) مختلفتين لفحص التكرار ما لم تُحذف المسافة الزائدة أولًا، لذا صُمِّم خيارا التشذيب وإزالة التكرار للعمل معًا لا كمفتاحين منفصلين.

الأسئلة الشائعة

لماذا يظهر "item10" قبل "item2" عندما أرتّب قائمتي؟

لأن الفرز الأبجدي البسيط يقارن النص حرفًا بحرف بدلًا من معاملة سلاسل الأرقام كأرقام كاملة — الحرف "1" أصغر من "2"، لذا يفوز item10 في تلك المقارنة أحادية الموضع رغم أن عشرة أكبر من اثنين. فعّل الفرز الطبيعي أو الرقمي لإصلاح ذلك: فهو يكتشف الأرقام المتتالية كرقم واحد ويقارن القيمة بدلًا من الأحرف الفردية.

ما الذي يُعدّ بالضبط سطرًا "مكررًا"؟

يُعدّ السطران مكررين فقط إذا تطابقا تمامًا، حرفًا بحرف، بما في ذلك حالة الأحرف وأي مسافات في البداية أو النهاية — تُعامَل "Apple" و"apple" كسطرين مختلفين، وكذلك "banana" و"banana " بمسافة زائدة. فعّل خيار التشذيب قبل إزالة التكرارات إذا أردت تجاهل فروق المسافات البيضاء.

هل يغيّر تشذيب المسافات البيضاء عدد التكرارات التي تُزال؟

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

هل localeCompare موثوقة لترتيب نصوص غير إنجليزية، مثل التركية أو الألمانية؟

نعم — localeCompare دالة مدمجة في المتصفح مصمَّمة خصيصًا للترتيب الصحيح حسب اللغة، فهي تعرف أن التركية تعامل "i" بنقطة و"ı" بلا نقطة كحرفين منفصلين، وتتعامل عمومًا مع الحروف المُشكَّلة بالطريقة التي يتوقعها قارئ تلك اللغة — وهو ما لا تستطيع مقارنة "أصغر من" البسيطة القائمة على نقاط كود يونيكود الخام فعله.

هل ترفع هذه الأداة نصي أو تخزّنه في أي مكان؟

لا — كل شيء يعمل محليًا في المتصفح باستخدام JavaScript؛ لا تُرسَل الأسطر أبدًا إلى خادم، ولا تُسجَّل، ولا تُحفَظ. تحديث الصفحة أو إغلاق التبويب يمسح المُدخل بالكامل تمامًا.

التعليقات

لا توجد تعليقات بعد — كن أول من يكتب تعليقًا!

أدوات مشابهة