طرق التعامل مع المصفوفات -الجزء الثالث JavaScript Methods Arrays part 3

-

بنحكي في هذا الدرس عن الترتيب Sorting في Arrays. ومن الميزات الرائعة في لغة JavaScript توفيرها طرقا مختلفة لترتيب القيم او العناصر داخلها.

بنحكي في هذ الدرس عن الطرق التالية:

  • ()sort
  • ()reverse
  • Numeric Sort
  • Compare Function
  • Sorting in Random Order
  • Fisher Yates Method
  • Highest (or Lowest) Array Value
  • Sorting Object Arrays
ترتيب القيم والعناصر داخل المصفوفة Sorting an Array

لترتيب القيم داخل المصفوفة يستخدم الامر ()sort وبتم عملية الترتيب بشكل أبجديا alphabetically

مثال:

<!DOCTYPE html>

<html>
<body onunload="">
<h3>JavaScript Array</h3>
<p id="Date"></p>
<script>
let Cars1 = ["BMW","Mercedes","Jaguar","Honda","Toyota","Mazada","Bentley","Ferrari","lamborghini"];
document.write("Before Sorting");
document.write("<br>");
document.write(Cars1);
document.write("<br>");
document.write("After Sorting");
document.write("<br>");
document.write(Cars1.sort());
document.write("<br>");
</script>
</body>
</html> 

النتيجة: 


عكس ترتيب المصفوفة Reversing an Array

لعكس ترتيب القيم داخل المصفوفة يستخدم الامر ()reverse وغالبا ما تستخدم لإجراء الترتيب بشكل تنازلي descending order ( من الأكبر الى الأصغر)

مثال :

<!DOCTYPE html>
<html>
<body onunload="">
<h3>JavaScript Array</h3>
<p id="Date"></p>
<script>
let Cars1 = ["BMW","Mercedes","Jaguar","Honda","Toyota","Mazada","Bentley","Ferrari","lamborghini"];
document.write("Before Sorting");
document.write("<br>");document.write("<br>");
document.write(Cars1);
document.write("<br>");document.write("<br>");
document.write("After Sorting");
document.write("<br>");document.write("<br>");
document.write(Cars1.sort());
document.write("<br>");document.write("<br>");
document.write("After Reversing ");
document.write("<br>");document.write("<br>");
document.write(Cars1.reverse());
document.write("<br>");
</script>
</body>
</html> 

النتيجة:


ترتيب الأرقام Numeric Sort

الوضع الافتراضي للغة JavaScript عند استخدام طريقة Sort تحويل القيم الى string حتى ولو كانت ارقام، وبناء عليه عند استخدام هذه الطريقة لترتيب الأرقام بتكون النتيجة خطأ (تماما مثل الاكسل اذا كان تعريف الاعمدة فيه على شكل text). 

نشوف مثال على ذلك :

<!DOCTYPE html>
<html>
<body onunload="">
<h3>JavaScript Array</h3>
<p id="Date"></p>
<script>
let Cars1 = [1,25,100,15,75,30];
document.write("Before Sorting");
document.write("<br>");document.write("<br>");
document.write(Cars1);
document.write("<br>");document.write("<br>");
document.write("After Sorting");
document.write("<br>");document.write("<br>");
document.write(Cars1.sort());
</script>
</body>
</html> 

النتيجة: 


لاحظ ان الرقم 100 اصبح في المرتبة رقم 2 يعني بناء على هذا الكلام 100 هو اصغر من 15 ، 25 ، 30 ... الخ. وهذا الحكي اكيد خطأ. السبب في هذا الخطأ لان الوضع الافتراضي في اللغة تحويل الأرقام الى string وبالتالي عند التحويل الى string بكون الرقم 25 اكبر من 100 لان المقارنة تبدأ من اول خانه وهي هنا 2 ( يعني 2 اكبر من 1 وبالتالي 25 ك string اكير من 100 ك string).

الحل في هذه الحالة هو استخدام وظائف المقارنة compare function

نطبق هذه الوظيفة في مثال وبعدها نفهم كيف بتعمل. 

<!DOCTYPE html>
<html>
<body onunload="">
<h3>JavaScript Array</h3>
<p id="Date"></p>
<script>
let Cars1 = [1,25,100,15,75,30];
document.write("Before Sorting");
document.write("<br>");document.write("<br>");
document.write(Cars1);
document.write("<br>");document.write("<br>");
document.write("After Sorting");
document.write("<br>");document.write("<br>");
document.write(Cars1.sort(function(a, b){return a - b}));
</script>
</body>
</html> 

النتيجة:


اكيد لاحظت ان تم ترتيب الأرقام بشكل صحيح.

تمام كيف هاذ الحكي بصير وشو معنى compare function

بداية لازم نفهم ان الغرض من وظائف المقارنة هي اجراء ترتيب بديل في حال تعذر الترتيب باستخدام الامر sort. 

تركيب الجملة بكون بالشكل التالي 

function compare(a,b) {
    return a - b;
}

لاحظ ان يجب ارسال 2 parameter وعادتا تكتب a,b بعدها بتم اجراء عملية حسابية وهي a-b 

النتيجة من هذه العملية الحسابية قيمة من 3 قيم وهي:

  • موجبة (اذا كانت a  اكبر من b )
  • 0 (اذا كانت a تساوي b )
  • سالبة ( اذا كانت a اقل  من b) 

عند استخدام sort() function لإجراء المقارنة يتم ارسال قيمتين الى compare function للمقارنة، بناء على القيم المرسلة بتم ارجاع النتائج (سالبة ، صفر ، موجبة).

تمام الان حسب النتيجة من compare function يتم اجراء الترتيب بالشكل التالي: 

  • اذا كانت النتيجة سالبة، هذا يعني بكون ترتيب a قبل b 
  • اذا كانت النتيجة موجبة، هذا يعني بكون ترتيب b قبل a 
  • إذا كانت النتيجة 0، فهذا يعني تساوي القيمتين وبالتالي بكون الهم نفس الترتيب.

نفهم كيف بتم تطبيق هذا الحكي 

في المثال السابق المصفوفة تحتوي القيم التالية:

let Cars1 = [1,25,100,15,75,30];

عملية المقارنة تتم على جميع الأرقام (يمعنى آخر يتم مقارنة الرقم 1 مع باقي الأرقام في المصفوفة، ثم مقارنة 25 مع باقي الأرقام وهكذا)

مثال على هذه العملية 

بنفس الطريقة لبقية الأرقام.
لترتيب المصفوفة بشكل عكسي نستخدم الطريقة
function compare(a,b) {
    return b -a;
}


ترتيب المصفوفة بطريقة عشوائية 
لتطبيق هذا الحكي بنستخدم الامر ()Math.random ، من خلال هذا الامر يمكن توليد رقم عشوائي 
مثال لتوليد الأرقام العشوائية :
<!DOCTYPE html>
<html>
<body onunload="">
<h3>JavaScript Array</h3>
<p id="Date"></p>
<script>
document.write(Math.random());
</script>
</body>
</html> 
النتيجة : رقم عشوائي مختلف في كل مرة. 

مثال على تريب المصفوفة بشكل عشوائي
<!DOCTYPE html>
<html>
<body onunload="">
<h3>JavaScript Array</h3>
<p id="Date"></p>
<script>
let Cars1 = [1,25,100,15,75,30];
document.write("Befor Sorting");
document.write("<br>");document.write("<br>");
document.write(Cars1);
document.write("<br>");document.write("<br>");
document.write("After Sorting");
document.write("<br>");document.write("<br>");
document.write(Cars1.sort(function(a, b){return 0.5-Math.random()}));
</script>
</body>
</html> 

النتيجة:  5 (النتيجة مختلفة كل مرة يعني لو عملت refresh  للصفحة اكيد بتكون النتيجة مختلفة)


طريقة او خوارزمية Fisher Yates
تم تقديم هذه الطريقة عام 1938 في علوم البيانات data science
تمام نشوف كيف ممكن نطبق هذه الطريقة في لغة JavaScript 
الشكل العام لهذه الخوارزمية 
To shuffle an array a of n elements (indices 0..n-1):
  for i from n - 1 downto 1 do
       j = random integer with 0 <= j <= i
       exchange a[j] and a[i]
تعمل خوارزمية Fisher – Yates العشوائية في تعقيد الوقت O (n). الافتراض هنا هو أننا حصلنا على ()function rand التي تولد رقمًا عشوائيًا في وقت O (1).
تكمن الفكرة في البدء من العنصر الأخير، ومبادلته بعنصر محدد عشوائيًا من المصفوفة بأكملها (بما في ذلك الأخير). الآن المصفوفة من 0 إلى n-2 (الحجم اقل بمقدار 1)، ثم يتم تكرار العملية حتى الوصول إلى العنصر الأول.
لتمثيل هذه الخوارزمية في لغة JavaScript 
طبق الكود التالي :
<!DOCTYPE html>
<html>
<body onunload="">
<h3>JavaScript Array</h3>
<p id="Date"></p>
<script>
let numbers = [1,25,100,15,75,30];
document.write("Befor Sorting");
document.write("<br>");document.write("<br>");
document.write(numbers);
for (let i = numbers.length -1; i > 0; i--) {
  let j = Math.floor(Math.random() * i)
  let k = numbers[i]
  numbers[i] = numbers[j]
  numbers[j] = k
}
document.write("<br>");document.write("<br>");
document.write("After Sorting");
document.write("<br>");document.write("<br>");
document.write(numbers);
</script>
</body>
</html> 

النتيجة: مختلفة في كل مرة بتعمل refresh  للصفحة .

الحصول على اعلى واقل قيمة في المصفوفة Find the Highest / Lowest Array Value
يمكن الوصول الى اعلى او اقل قيمة في المصفوفة باستخدام طريقتين. 
  • الطريقة الأولى هي ترتيب المصفوفة بشكل تصاعدي او تنازلي ومن ثم استخدام index 
  • الطريقة الثانية باستخدام function يحتوي على Math.max.apply او Math.min.apply
تمام نفهم هذا الحكي. 
الطريقة الاولي باستخدام index
الفكرة هون هي ترتيب المصفوفة بشكل تصاعدي او تناولي ثم من خلال index بنرجع اول قيمة (index=0) واخر قيمة (index=array.lenght-1) 
اكيد بكون اول قيمة واخر قيمة بعتمد على نوع الترتيب للمصفوفة 
بمعنى اذا كان الترتيب تصاعدي Ascending من الأصغر الى الأكبر بكون اول قيمة هي اصغر قيمة في المصفوفة واخر قيمة هي اكبر قيمة في المصفوفة. 
واذا الترتيب تنازلي Descending من الاكبر الى الاصغر بكون اول قيمة هي اكبر قيمة في المصفوفة واخر قيمة هي اصغر قيمة في المصفوفة. 
نطبق مثال على هذا الحكي حتى نفهم الموضوع.
باستخدام الترتيب التصاعدي Ascending
<!DOCTYPE html>
<html>
<body onunload="">
<h3>JavaScript Array</h3>
<p id="Date"></p>
<script>
let Cars1 = [1,25,100,15,75,30];
Cars1.sort(function(a, b){return a - b})
document.write("Max Value");
document.write("<br>");document.write("<br>");
document.write(Cars1[Cars1.length-1]);
document.write("<br>");document.write("<br>");
document.write("lowest  Value");
document.write("<br>");document.write("<br>");
document.write(Cars1[0]);
</script>
</body>
</html> 
النتيجة: 

باستخدام الترتيب تنازلي Descending
مثال:
<!DOCTYPE html>
<html>
<body onunload="">
<h3>JavaScript Array</h3>
<p id="Date"></p>
<script>
let Cars1 = [1,25,100,15,75,30];
Cars1.sort(function(a, b){return b - a})
document.write(Cars1);
document.write("<br>");document.write("<br>");
document.write("Max Value");
document.write("<br>");document.write("<br>");
document.write(Cars1[0]);
document.write("<br>");document.write("<br>");
document.write("lowest  Value");
document.write("<br>");document.write("<br>");
document.write(Cars1[Cars1.length-1]);
</script>
</body>
</html> 
النتيجة: 

الطريقة الثانية باستخدام Math.max.apply او Math.min.apply
مثال :
<!DOCTYPE html>
<html>
<body onunload="">
<h3>JavaScript Array</h3>
<p id="Date"></p>
<script>
let Cars1 = [1,25,100,15,75,30];
document.write("Max Value");
document.write("<br>");document.write("<br>");
document.write(Math.max.apply(null, Cars1));
document.write("<br>");document.write("<br>");
document.write("lowest  Value");
document.write("<br>");document.write("<br>");
document.write(Math.min.apply(null, Cars1));
</script>
</body>
</html> 
النتيجة: 

الفكرة في هذا function : يتم قراءة جميع القيم الموجودة في المصفوفة وارجاع اكبر قيمة او اصغر قيمة.
في حال الحصول على اكبر قيمة بكون الكود السابق يعادل 
Math.max(1,25,100,15,75,30);
وفي حال الحصول على اصغير قيمة بكون الكود يعادل
Math.min(1,25,100,15,75,30);

ترتيب المصفوفات التي تحتوي على object Sorting Object Arrays
حكينا ان المصفوفات ممكن ان تحتوي على object، وحكينا ان object يمكن الوصول الى القيم فيها عن طريق الاسم. واكيد كمان ممكن ترتيب القيم داخل المصفوفة المكونة من object. نشوف كيف بنطبق هذا الحكي.
الحل هو استخدام compare function
مثال:
<!DOCTYPE html>
<html>
<body onunload="">
<h3>JavaScript Array</h3>
<p id="demo"></p>
<script>
const cars = [
  {type:"Honda", year:2022},
  {type:"BMW", year:2019},
  {type:"Mercedes", year:2023}
];
cars.sort(function(a, b){return a.year - b.year});
displayCars();
function displayCars() {
  document.getElementById("demo").innerHTML =
  cars[0].type + " " + cars[0].year + "<br>" +
  cars[1].type + " " + cars[1].year + "<br>" +
  cars[2].type + " " + cars[2].year;
}
</script>
</body>
</html> 

النتيجة: 

الفكرة في المثال السابق عرفنا مصفوفة باسم cars تحتوي على object لاسم ونوع السيارة، بعد هيك عملنا ترتيب لمكونات المصفوفة باستخدام طريقة compare function وبعدها استدعينا function باسم displayCars يتم من خلاله طباعة مكونات المصفوفة على الشاشة .