اذهب إلى المحتوى

السؤال

نشر

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

orderWeight.js

Recommended Posts

  • 0
نشر

وعليكم السلام ورحمة الله وبركاته.

في جافاسكريبت الكائنات (Objects) هي عبارة عن مجموعات من الأزواج تتكون من مفتاح (key) و قيمة (value). وإن الكائنات في جافاسكريبت لا تحتفظ بترتيب محدد للخصائص ا(لمفاتيح) الخاصة بها. أى أن البيانات لا يتم تخزينها دائما بنفس الترتيب الذي تمت إضافتها به مثل المصفوفات ولا يمكن الاعتماد على ترتيب البيانات عند التكرار عبر الكائن.

في المواصفات الرسمية لجافاسكريبت (ECMAScript)، لا يتم ضمان ترتيب الخصائص في الكائنات. قبل الإصدار ES6 كانت معظم المتصفحات تعرض الخصائص بنفس الترتيب الذي تمت إضافتها به لكن هذا لم يعد السلوك الحالي منذ ES6 حيث تم تحديد بعض القواعد لترتيب الخصائص لكنها لا تنطبق على جميع الحالات.

حيث القواعد الحالية لترتيب الخصائص:

  • المفاتيح الرقمية (أرقام): يتم ترتيبها تصاعديا.
  • المفاتيح النصية (strings): يتم ترتيبها حسب الترتيب الذي تمت إضافتها به.
  • المفاتيح من نوع Symbol: يتم ترتيبها حسب الترتيب الذي تمت إضافتها به.

ولكن كما وضحت لك هذا الترتيب ليس مضمونا.

لنرى المثال التالي :

let obj = {
    "b": 2,
    "a": 1,
    3: "three",
    1: "one"
};

console.log(obj); // { '1': 'one', '3': 'three', b: 2, a: 1 }
console.log(Object.keys(obj)); // قد يعطي ["1", "3", "b", "a"] أو ["1", "3", "a", "b"]

لاحظ كيف في الكائن السابق تم ترتيب المفاتيح التي هي أرقام أولا ترتيب تصاعدي حيث تم وضع 1 أولا و من ثم 3 . وبعد ذلك المفاتيح النصية تم ترتيبها بناء على الترتيب التي تم وضعها به . حيث تم وضع b أولا قبل a حين أنشأنا الكائن لهذا ظهرت b قبل 2 . ولكن كما وضحت لك هذا الترتيب ليس مضمون الحصول عليه.

المشكلة الرئيسية لديك في دالة reduce حيث أنت تقوم بإنشاء كائن وتقوم بوضع الخصائص به وتجعل المفاتيح له هي أرقام لهذا يتم ترتيبها تصاعديا .حيث كما وضحت لك أن javascript تقوم بترتيب الكائن بالقواعد السابقة التي وضحتها وليس كما قمت أنت بوضعها . لهذا يتم ترتيب العنصر بشكل مختلف عن الذي أنشأته . 

والحل الأفضل لك هو إستخدام Map بدلا من ال obj في دالة reduce هكذا :

function orderWeight(strng) {
  // "103 123 4444 99 2000" => "2000 103 123 4444 99"
  let arr = strng.split(" ");
  let weightsObject = {};
  arr.map((number)=>{
    let total = 0;
    let chars = number.split("")
    chars.map((char)=>{
      total += +char;
    })
    return weightsObject[number] = total;
  })
  let sortedValues = Object.entries(weightsObject)
  .sort(([, a], [, b]) => a - b)
  .reduce((acc, [key, val]) => (acc.set(key, val)), new Map());
  
  console.log(sortedValues);
  console.log(weightsObject);
}
orderWeight("100 180 90 56 65 74 68 86 99")

وستجد أنه تم التريتب بناء على ترتيب وضع الخصائص وليس كما تفعل الكائنات.

  • 0
نشر

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

وحساب الوزن باستخدام reduce، لحساب مجموع الأرقام لكل عدد بطريقة أكثر كفاءة، ثم الترتيب باستخدام الوزن والترتيب الأبجدي أي عند تساوي الوزن، نقارن الأرقام كسلاسل نصية باستخدام ميثود localeCompare.

وعليك معالجة الفراغات من خلال ميثودز trim() و split(/\s+/) للتأكد من التعامل مع الفراغات الزائدة بشكل صحيح.

function orderWeight(strng) {
  const numbers = strng.trim().split(/\s+/).filter(n => n !== '');
  if (numbers.length === 0) return '';

  return numbers
    .map(num => ({
      num,
      weight: num.split('').reduce((sum, digit) => sum + parseInt(digit, 10), 0)
    }))
    .sort((a, b) => {
      if (a.weight === b.weight) {
        return a.num.localeCompare(b.num);
      }
      return a.weight - b.weight;
    })
    .map(entry => entry.num)
    .join(' ');
}

console.log(orderWeight("56 65 74 100 99 68 86 180 90")); 

ما قمت به هو تقسيم السلسلة المدخلة إلى مصفوفة من الأرقام مع تجاهل الفراغات الزائدة، وحساب الوزن لكل عدد: بحساب مجموع أرقامه بمعنى 100 هي 1+0+0 = 1.

ثم نرتب المصفوفة حسب الوزن، وفي حالة التساوي نرتب أبجديًا، ثم إعادة تجميع النتيجة باستخراج الأرقام المرتبة ونضمّنها في سلسلة واحدة.

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...