If الشرطية (متوسط)

الشروط المتداخلة (Nested If)

في بعض اﻷحيان... تحتاج لأن تكتب جملة شرط داخل جملة شرط أخرى! فمثلاً لدينا بريد إلكتروني، ولدينا كلمة سر، ونريد أن نفعل التالي:

  • نكتب شرط للتحقق من البريد اﻹلكتروني
  • فإن تحقق الشرط وكان البريد صحيحاً:
    • يكون هناك شرطاً آخر يتحقق من كلمة السر، فإن كانت صحيحة يطبع "تم تسجيل الدخول"
    • أما إن كانت كلمة السر غير صحيحة يطبع "كلمة السر غير صحيحة"
  • وإن لم يتحقق شرط البريد اﻹلكتروني وكان خطأ، يتم طباعة "البريد اﻹلكتروني غير صحيح" بدون أن يتم التحقق أساسا من كلمة السر، مادام البريد غير صحيحاً إذن لا يكمل!

في هذه الحالة سنستخدم الشروط المتداخلة (Nested If)، سنحتاج لكتابة شرط للتحقق من البريد اﻹلكتروني، وبداخله شرط آخر يتحقق من كلمة السر، وشرط كلمة السر بما أنه داخل شرط البريد اﻹلكتروني؛ إذن لن يصل إليه المفسر إلا في حالة أن البريد اﻹلكتروني صحيح (تحقق الشرط الأول.. شرط البريد اﻹلكتروني)

مثال تسجيل الدخول

مثال لبرنامج مبسيط يسمح بتسجيل الدخول إن كان البريد اﻹلكتروني "dalilmobarmg@gmail.com" وكلمة السر "123456" فقط!

var email = "test@gmail.com"; // enter email here
var password = "password"; // enter password here

if (email == "dalilmobarmg@gmail.com"){
  if (password == "123456"){
    console.log("تم تسجيل الدخول بنجاح");
  }else{
    console.log("كلمة السر غير صحيحة");
  }
}else{
  console.log("البريد اﻹلكتروني غير صحيح");
}

في المثال السابق سيتحقق المفسر من شرط اﻹيميل، هل اﻹيميل يساوي "dalilmobarmg@gmail.com" ? إذا كان نعم سيدخل المفسر داخل كتلة اﻷوامر وبالتالي سيجد شرطاً ثانياً (شرط كلمة السر) ليتحقق منه، أما إذا لم يتحقق الشرط اﻷول فسيذهب المفسر مباشرة إلى else اﻷخيرة ليطبع "البريد اﻹلكتروني غير صحيح" ...

بإختصار: داخل أي كتلة أوامر {} يمكنك كتابة أي عدد من الشروط! سواء كانت كتلة أوامر if أو else أو حتى حلقة تكرارية أو أي كتلة.

مثال تقدير نجاح الطالب

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

  • من 0 إلى 50 يكون راسب
  • من 50 إلى 65 يكون "مقبول"
  • من 65 إلى 80 يكون "جيد"
  • من 80 إلى 90 يكون "جيد جداً"
  • من 90 إلى 100 يكون ممتاز

ويمكننا تنفيذها بعدة خوارزميات مختلفة:

الخوارزمية اﻷولى

  • إذا كانت درجة الطالب أقل من 50 إذن هو راسب
  • غير ذلك (أي درجته أعلى من 50) إذا كانت درجة الطالب أقل من 65 إذن هو مقبول
  • غير ذلك إذا كانت درجة الطالب أقل من 80 إذن التقدير جيد
  • غير ذلك، إذا كانت درجة الطالب أقل من 90 إذن التقدير جيد جداً
  • غير ذلك يكون التقدير ممتاز
function rating(score){
  if (score < 50){
    console.log("راسب");
    
  }else{
    if (score < 65){
      console.log("مقبول");

    }else{
      if (score < 80){
        console.log("جيد");

      }else{
        if (score < 90){
          console.log("جيد جداً");

        }else{
          console.log("ممتاز");
        }
      }
    }
  }
}

rating(40);
rating(60);
rating(70);
rating(84);
rating(95);
ناتج التشغيل راسب
مقبول
جيد
جيد جداً
ممتاز

الكود معقد جداً ككتابة، لذلك سنتعلم لاحقاً في نفس الدرس أمور جديدة لتنفيذ نفس الخوارزمية بكود أسهل وأكثر اختصاراً!

في نهاية الكود ستجد 5 أقواس { والسبب أن لدينا قوس كتلة الدالة، و4 أقواس كتلة else ﻷن لدينا 4 else

المسافات في الكود مهمتها تنسيق الكود لتسهيل قراءته، دائما الكود بداخل الكتلة (block) يبدأ بمسافة حتى تتمكن العين من ملاحظة أنه بداخل هذه الكتلة، سيعمل الكود إذا لم تنسقه أيضاً لكن طريقة كتابته ستكون سيئة جداً صعبة القراءة، لذلك احرص دائما على تنسيق الكود وكتابته بالطريقة اﻷفضل

يمكنك إضافة المسافات المستخدمة في تنسيق الكود بالضغط على الزر Tab الموجود أعلى يسار لوحة المفاتيح بجوار حرف Q


الخوارزمية الثانية

  • إذا كانت درجة الطالب أكبر من أو تساوي 90 إذن التقدير ممتاز
  • غير ذلك إذا كانت درجة الطالب أكبر من أو تساوي 80 إذن التقدير جيد جداً
  • غير ذلك إذا كانت درجة الطالب أكبر من أو تساوي 65 إذن التقدير جيد
  • غير ذلك إذا كانت درجة الطالب أكبر من أو تساوي 50 إذن التقدير مقبول
  • غير ذلك يكون الطالب راسب
function rating(score){
  if (score >= 90){
    console.log("ممتاز");

  }else{
    if (score >= 80){
      console.log("جيد جداً");

    }else{
      if (score >= 65){
        console.log("جيد");

      }else{
        if (score >= 50){
          console.log("مقبول");

        }else{
          console.log("راسب");

        }
      }
    }
  }
}

rating(40);
rating(60);
rating(70);
rating(84);
rating(95);
ناتج التشغيل راسب
مقبول
جيد
جيد جداً
ممتاز

وبنفس الطريقة اعلم أنه يمكن تنفيذ فكرة واحدة بعدة خوارزميات، أو خوارزمية واحدة بأكواد مختلفة.


غير ذلك لو else if

جاء موعد الحديث عن أمر جميل جداً، يساعد في إختصار الشروط وكتابة كود أسرع وأكثر قابلية للقراءة وأسهل! وهو الأمر else if وربما قد فهمت معناه من اسمه، فهذا الأمر يتنفذ إذا لم يتحقق الشرط اﻷول، في حالة تحقق الشرط الذي يليه، يعني كأنك تقول للمفسّر "غير ذلك لو..."

طريقة كتابة else if

if (){
  
}else if (){

}else{

}

مثال بسيط على else if

نريد كتابة كود يطبع "موجب" إذا كان العدد أكبر من صفر، غير ذلك يطبع "سالب" إذا كان العدد أصغر من الصفر، غير ذلك يطبع "صفر"

function positiveOrNegative(num){
  if (num > 0){
    console.log("موجب");
  }else if (num < 0){
    console.log("سالب");
  }else{
    console.log("صفر");
  }
}

positiveOrNegative(73);
positiveOrNegative(5);
positiveOrNegative(0);
positiveOrNegative(-5);
ناتج التشغيل موجب
موجب
صفر
سالب

مثال الطالب باستخدام else if

هذا استخدام حقيقي لـ else if يوضح مدى سهولتها وأهميتها... راجع هذا المثال باﻷعلى وانظر الفرق بين كتابة الكود هنا وهناك!

function rating(score){
  if (score >= 90){
    console.log("ممتاز");

  }else if (score >= 80){
    console.log("جيد جداً");

  }else if (score >= 65){
    console.log("جيد");

  }else if (score >= 50){
    console.log("مقبول");
  }else{
    console.log("راسب");
  }
}

rating(40);
rating(60);
rating(70);
rating(84);
rating(95);
ناتج التشغيل راسب
مقبول
جيد
جيد جداً
ممتاز

في الشروط، يقوم المفسر بتنفيذ كتلة أوامر واحدة فقط، مثلاً لدينا كتلة أوامر if ولدينا 3 كتلات else if ولدينا كتلة else، بكل تأكيد سيقوم المفسر بتنفيذ كتلة واحدة فقط من الخمس كتلات، ﻷن أول شرط سيتحقق سيقوم بتنفيذ كتلته، وإن لم يتحقق الكل سيقوم بتنفيذ كتلة else

الشروط والقيمة الفارغة

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

function getEven(numbers){
  var result = [];

  var i = 0;
  while (i < numbers.length){
    var num = numbers[i];
    if (num % 2 == 0){
      result.push(num);
    }
    i += 1;
  }

  if (result.length > 0){
    return result;
  }else{
    return null;
  }
}

console.log( getEven([1,2,3,4,5,6]) )
ناتج التشغيل [2,4,6]

يٌفضل اختصار الشرط result.length > 0 وكتابته result.length ﻷن في كل اﻷحوال كما درسنا في درس التحويل المنطقي إذا كانت قيمة result.length تساوي صفر فسيعتبرها المفسر بكل تأكيد false

الشروط يمكن كتابتها بطرق كثيرة، لذلك اختر دائما اﻷفضل واﻷسرع تنفيذاً واﻷكثر اختصاراً، استخدم else if في المواقف التي هي أسرع فيها وأكثر اختصاراً، كذلك استخدم التعبيرات المنطقية ﻷنها ستختصر عليك الكثير! فبدلاً من أن تكتب أكثر من شرط متداخل، يمكنك دمجهم في شرط واحد باستخدام العلامة &&، وهكذا...

القيمة الفارغة

واﻵن لنستخدم الدالة السابقة، ولكن نريد أن نقوم بطباعة اﻷعداد الزوجية التي وجدناها إن وُجدت، غير ذلك نريد طباعة "لم نجد أعداداً زوجية"

في هذا المثال تحتوي المصفوفة على أعداد فردية فقط، بالتالي ستقوم الدالة getEven بإرجاع null

var even = getEven([1,3,5]);
if (even){
  console.log(even);
}else{
  console.log("لا يوجد أعداد زوجية");
}
ناتج التشغيل لا يوجد أعداد زوجية

في الكود السابق أنشأنا متغير اسمه even ستكون قيمته تساوي الراجع من الدالة getEven وفي هذه الحالة ستقوم الدالة بإرجاع null مما سيساعدنا في الشرط، قمنا بإنشاء شرط يتحقق من قيمة المتغير even وكما قلنا في درس التحويل المنطقي فإن الشرط سيتحول إلى قيمته المنطقية، وبالتالي إذا كانت قيمته null فإنه سيعتبرها false ولن يتحقق الشرط، وسيقوم بتنفيذ كتلة أوامر else... لذلك في المثال السابق سيقوم بطباعة "لا يوجد أعداد زوجية" ﻷن قيمة even تساوي null

وهنا تظهر أهمية null خصوصا مع الشروط

الشروط والمصفوفات

ماذا لو في الدالة السابقة تقوم الدالة بإرجاع مصفوفة فارغة [] بدلاً من أن تقوم الدالة بإرجاع null في حالة عدم وجود أعداد زوجية.! كيف نتحقق من أن الدالة قامت بإرجاع أعداد زوجية أم ﻻ!

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

var even = getEven([1,3,5]);
if (even.length){
  console.log(even);
}else{
  console.log("لا يوجد أعداد زوجية");
}

هناك لغات برمجة تعتبر المصفوفة الفارغة false وهناك لغات أخرى كلغة جافاسكريبت تعتبرها true لذلك يُفضل التحقق من المصفوفة بطريقة "طول المصفوفة" حتى لا يحدث خطأ!

ماذا لو لم أعرف هل الدالة تقوم بإرجاع مصفوفة أم null ؟

لنتخيل أن الدالة تقوم بإرجاع null إذا لم تجد أعداد زوجية، واستخدمنا طريقة طول المصفوفة even.length بسبب أننا كنا نتخيل أنها ستقوم بإرجاع مصفوفة فارغة! في هذه الحالة سيكون الشرط even.length يساوي null.length وبالتالي سيقوم المفسر بإعطاء النتيجة خطأ ﻷن .length تستخدم مع المصفوفات وليس مع null!

والحل للمشكلة السابقة: يمكننا باستخدام العلامة && في كتابة الشرطين في شرط واحد!

  • نتحقق اﻷول من even... فإذا كانت قيمته null سيعتبرها المفسر منطقياً false وبالتالي لن يتحقق الشرط، وهو المطلوب
  • وإن كانت قيمته تساوي true (وهذا سيحدث في حالة إرجاع مصفوفة فارغة [] سيعتبرها المفسر منطقياً true) نقوم بالتحقق من طول المصفوفة!

وبالتالي سيكون الشرط: even && even.length

var even = getEven([1,3,5]);
if (even && even.length){
  console.log(even);
}else{
  console.log("لا يوجد أعداد زوجية");
}

الكود السابق سيعمل في حالة أن الدالة تقوم بإرجاع null أو تقوم بإرجاع مصفوفة فارغة []!

عند استخدام العلامة && يتحقق المفسر من الشرط اﻷول، إن لم يتحقق يعتبر أن التعبير المنطقي كاملاً يساوي false... أما إن تحقق فيذهب للشرط الثاني ويتحقق منه... لذلك لن يذهب المفسر للشرط الثاني إلا إذا تحقق اﻷول!

تهانينا... أنت اﻵن درست كل ما ستحتاج تقريباً في الشروط، وعرفت كل المشاكل التي ستواجهك أثناء استخدام الشروط والتعبيرات المنطقية... ولذلك أنت اﻵن تستطيع التفكير كمبرمج! التفكير المنطقي.

المساهمين

وجدت خطأ أو تريد المساهمة في محتوى الدرس؟ عدل الصفحة على Github