{"id":"l-js-3-1","courseId":"javascript-fundamentals","lang":"ar","kind":"lesson","summary":"تُنشئ المصفوفات وتغيّرها، وتعرف أيّ دوالها تعدّلها في مكانها، وتستبدل الحلقات المكتوبة يدويًا بـ map وfilter وfind وsome وevery لتحويل القوائم والبحث فيها.","html":"<p>مصاريف Pocket قائمة، ومعظم ميزاته أسئلة حول هذه القائمة. أيّها مبالغ مستردّة؟ كيف تبدو منسّقة بالدولار؟ هل يوجد ما يتجاوز 100 دولار؟ يمكنك الإجابة عن كل هذا بحلقات القسم 2، لكن المصفوفات تأتي مع دوال (methods) تجيب عن كل سؤال منها بسطر واحد مقروء.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">إنشاء المصفوفات وتغييرها</h2>\n<p>المصفوفة قائمة مرتّبة من القيم. وقد رأيت أساسياتها: أقواس مربّعة، ومواضع تبدأ من 0، و<code dir=\"ltr\">length</code>.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"0\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amounts</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">270</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">push</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">899</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);           </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// add to the end</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(amounts);</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> last</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">pop</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">();  </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// remove from the end, and get it back</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(last, amounts);</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">amounts[</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">] </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 500</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;            </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// replace an item by index</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(amounts, amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">includes</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">), amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">indexOf</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">270</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));</span></span></code></pre><div class=\"run-output\" data-run-output=\"0\" hidden></div></div>\n<p>لحظة: <code dir=\"ltr\">amounts</code> مُصرَّح بها بـ <code dir=\"ltr\">const</code>، ومع ذلك تغيّرت ثلاث مرات. ليس في هذا تناقض. <code dir=\"ltr\">const</code> تعني أن <strong>الاسم</strong> يشير دائمًا إلى المصفوفة نفسها، ولا تقول شيئًا عمّا بداخلها. <code dir=\"ltr\">push</code> و<code dir=\"ltr\">pop</code> والإسناد بالفهرس كلها تغيّر محتويات تلك المصفوفة الواحدة، لذلك هي مسموحة. وحدها <code dir=\"ltr\">amounts = [...]</code>، أي توجيه الاسم إلى مصفوفة مختلفة، هي التي ترمي خطأ.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 640 200\" role=\"img\" aria-labelledby=\"l-js-3-1-t1\"><defs><marker id=\"arrow-l-js-3-1-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-js-3-1-t1\">الاسم amounts المُصرَّح به بـ const يشير إلى مصفوفة واحدة. push تغيّر العناصر داخل تلك المصفوفة، وهذا مسموح. أما توجيه amounts إلى مصفوفة أخرى فهو ما تمنعه const.</title>\n  <rect class=\"d-box-primary\" x=\"20\" y=\"70\" width=\"160\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"100\" y=\"100\" text-anchor=\"middle\">const amounts</text>\n  <path class=\"d-arrow\" d=\"M180 95 L256 95\" marker-end=\"url(#arrow-l-js-3-1-1)\"/>\n  <rect class=\"d-box\" x=\"260\" y=\"60\" width=\"360\" height=\"70\" rx=\"12\"/>\n  <text class=\"d-code\" x=\"440\" y=\"100\" text-anchor=\"middle\">[450, 1220, 270, 899]</text>\n  <text class=\"d-label-muted\" x=\"440\" y=\"160\" text-anchor=\"middle\">push / pop / [0] = … تغيّر الصندوق: مسموح</text>\n  <text class=\"d-label-muted\" x=\"220\" y=\"40\" text-anchor=\"middle\">إعادة توجيه السهم: TypeError</text>\n</svg><figcaption>const تثبّت السهم، لا المحتويات</figcaption></figure>\n<p>هذه الفكرة، أن الاسم يشير إلى قائمة وأن عدّة عمليات تغيّر القائمة نفسها، هي سبب ضرورة معرفة أيّ الدوال <strong>تعدّل في المكان</strong> (mutate):</p>\n<div class=\"table-wrap\" role=\"region\" aria-label=\"جدول قابل للتمرير\" tabindex=\"0\"><table><thead>\n<tr>\n<th>تغيّر المصفوفة نفسها</th>\n<th>تُرجع شيئًا جديدًا وتترك المصفوفة كما هي</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code dir=\"ltr\">push</code>، <code dir=\"ltr\">pop</code>، <code dir=\"ltr\">shift</code>، <code dir=\"ltr\">unshift</code></td>\n<td><code dir=\"ltr\">slice</code>، <code dir=\"ltr\">concat</code></td>\n</tr>\n<tr>\n<td><code dir=\"ltr\">splice</code></td>\n<td><code dir=\"ltr\">map</code>، <code dir=\"ltr\">filter</code></td>\n</tr>\n<tr>\n<td><code dir=\"ltr\">sort</code>، <code dir=\"ltr\">reverse</code></td>\n<td><code dir=\"ltr\">toSorted</code>، <code dir=\"ltr\">toReversed</code></td>\n</tr>\n</tbody>\n</table></div><p>التعديل في المكان ليس خطأً، لكنه يفاجئ الناس حين يتشارك جزءان من البرنامج مصفوفة واحدة. والدوال في باقي هذا الدرس لا تعدّل في المكان أبدًا، وهذا جزء كبير من سبب شعبيتها.</p>\n<p>والثنائي الذي يُربك الجميع هو <code dir=\"ltr\">slice</code> و<code dir=\"ltr\">splice</code>، يفصل بينهما حرف واحد وسلوكهما متعاكس:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"1\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amounts</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">270</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">899</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> firstTwo</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">slice</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);   </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// copy of indexes 0 and 1</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(firstTwo, amounts);         </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// original untouched</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> removed</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">splice</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);   </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// remove 1 item at index 1</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(removed, amounts);          </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// original changed</span></span></code></pre><div class=\"run-output\" data-run-output=\"1\" hidden></div></div>\n<p><code dir=\"ltr\">slice(start, end)</code> تعمل تمامًا مثل دالة النصوص التي تحمل الاسم نفسه: تنسخ جزءًا وتترك الأصل دون مساس. أما <code dir=\"ltr\">splice(start, count)</code> فتقصّ عناصر من المصفوفة نفسها وتُرجع ما أزالته. وإن احتجت يومًا إلى إزالة عنصر دون تغيير الأصل، فاستخدم <code dir=\"ltr\">filter</code> بدلًا منها، وستتعرّف عليها حالًا.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">map: حوّل كل عنصر</h2>\n<p>تستدعي <code dir=\"ltr\">map</code> دالة لكل عنصر، وتجمع القيم المُعادة في <strong>مصفوفة جديدة بالطول نفسه</strong>:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"2\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amounts</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">270</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> formatMoney</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#953800;--shiki-dark:#FFA657\">cents</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> `$${</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">cents</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> /</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">).</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">toFixed</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">)</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> labels</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">map</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(formatMoney);</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(labels);</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(amounts);  </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// unchanged</span></span></code></pre><div class=\"run-output\" data-run-output=\"2\" hidden></div></div>\n<p>إنها النسخة المدمجة من دالة <code dir=\"ltr\">applyToAll</code> التي كتبتها في درس الدوال. استخدم <code dir=\"ltr\">map</code> كلما كان السؤال “حوّل كل X إلى Y”: السنتات إلى نصوص بالدولار، أو الدولارات إلى سنتات، أو قيم النموذج الخام إلى قيم نظيفة. يستلم الـ callback كل عنصر بدوره، ويجب أن يُرجع نسخته الجديدة. وكل ما يُرجعه يوضع في الموضع نفسه من النتيجة، لذلك يكون في المخرجات دائمًا عدد العناصر نفسه الذي في المدخلات.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">filter: احتفظ ببعض العناصر فقط</h2>\n<p>تستدعي <code dir=\"ltr\">filter</code> دالة اختبار لكل عنصر، وتُرجع مصفوفة جديدة فيها فقط العناصر التي أرجع لها الاختبار قيمة truthy:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"3\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amounts</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">300</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">50</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">270</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> spending</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">filter</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">a</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> a </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> refunds</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">filter</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">a</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> a </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">&#x3C;</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(spending, refunds);</span></span></code></pre><div class=\"run-output\" data-run-output=\"3\" hidden></div></div>\n<p>قد تكون النتيجة أقصر من الأصل، بل قد تكون فارغة، لكن <code dir=\"ltr\">filter</code> لا تغيّر العناصر نفسها أبدًا.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">find وsome وevery: البحث</h2>\n<p>أربع دوال تجيب عن أسئلة البحث، وكل منها تتوقّف بمجرّد أن تعرف الإجابة:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"4\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amounts</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">12000</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">15000</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">find</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">a</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> a </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">>=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 10000</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));       </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// first match: 12000</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">findIndex</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">a</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> a </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">>=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 10000</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));  </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// its position: 1</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">some</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">a</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> a </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">&#x3C;</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));            </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// any refunds? false</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">every</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">a</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> a </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">));           </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\">// all positive? true</span></span></code></pre><div class=\"run-output\" data-run-output=\"4\" hidden></div></div>\n<p><code dir=\"ltr\">find</code> تُرجع العنصر نفسه، أو <code dir=\"ltr\">undefined</code> إن لم يطابق شيء. و<code dir=\"ltr\">findIndex</code> تُرجع موضعه، أو <code dir=\"ltr\">-1</code>. أما <code dir=\"ltr\">some</code> و<code dir=\"ltr\">every</code> فتُرجعان قيمًا منطقية: “واحد على الأقل” و&quot;جميعها&quot;.</p>\n<h2 id=\"sec-5\" tabindex=\"-1\">السلسلة: قراءة خطّ معالجة</h2>\n<p>لأن <code dir=\"ltr\">filter</code> و<code dir=\"ltr\">map</code> كلتيهما تُرجعان مصفوفات، يمكنك استدعاء إحداهما على ناتج الأخرى:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"5\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"5\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amounts</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">300</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">12000</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> bigOnes</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> amounts</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  .</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">filter</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">a</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> a </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">>=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 1000</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  .</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">map</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">a</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> `$${</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">a</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> /</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">).</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">toFixed</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">)</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(bigOnes);</span></span></code></pre><div class=\"run-output\" data-run-output=\"5\" hidden></div></div>\n<p>اقرأها من الأعلى إلى الأسفل كوصفة طبخ: ابدأ بكل المبالغ، واحتفظ بما قيمته 10 دولارات أو أكثر، ثم نسّقها. كل خطوة تستلم مخرجات الخطوة التي قبلها. ووضع كل خطوة في سطر خاص بها يبدأ بالنقطة يُبقي السلاسل الطويلة مقروءة.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">خطأ شائع</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>أقواس معقوفة دون return في الـ callback</span></p>\n<p><code dir=\"ltr\">amounts.map((a) =&gt; { a / 100 })</code> تُرجع <code dir=\"ltr\">[undefined, undefined, …]</code>، و<code dir=\"ltr\">filter</code> مع الخطأ نفسه تُرجع <code dir=\"ltr\">[]</code>، لأن <code dir=\"ltr\">undefined</code> قيمة falsy. مع الأقواس المعقوفة، يحتاج الـ callback إلى <code dir=\"ltr\">return</code>. ومع تعبير واحد، احذف الأقواس: <code dir=\"ltr\">amounts.map((a) =&gt; a / 100)</code>.</p>\n</aside>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">نصيحة</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>forEach للتأثيرات الجانبية</span></p>\n<p>للمصفوفات أيضًا <code dir=\"ltr\">forEach</code>، التي تستدعي دالة لكل عنصر ولا تُرجع شيئًا. استخدمها، أو <code dir=\"ltr\">for...of</code>، حين تريد أن <em>تفعل</em> شيئًا مع كل عنصر، مثل الطباعة. واستخدم <code dir=\"ltr\">map</code> و<code dir=\"ltr\">filter</code> حين تريد استعادة مصفوفة جديدة.</p>\n</aside>\n<p>حتى الآن تحمل المصفوفات أرقامًا بسيطة. لكن المصاريف الحقيقية لها تسمية ومبلغ وفئة معًا، وهذا يستدعي الكائنات، موضوع الدرس التالي.</p>\n","toc":[{"id":"sec-1","text":"إنشاء المصفوفات وتغييرها","level":2},{"id":"sec-2","text":"map: حوّل كل عنصر","level":2},{"id":"sec-3","text":"filter: احتفظ ببعض العناصر فقط","level":2},{"id":"sec-4","text":"find وsome وevery: البحث","level":2},{"id":"sec-5","text":"السلسلة: قراءة خطّ معالجة","level":2}],"takeaways":["<code dir=\"ltr\">const</code> تمنع الاسم من الإشارة إلى مصفوفة أخرى، لكن محتويات المصفوفة نفسها يمكن أن تتغيّر عبر <code dir=\"ltr\">push</code> أو <code dir=\"ltr\">pop</code> أو الإسناد بالفهرس.","بعض الدوال تعدّل المصفوفة نفسها (<code dir=\"ltr\">push</code> و<code dir=\"ltr\">pop</code> و<code dir=\"ltr\">splice</code> و<code dir=\"ltr\">sort</code>)؛ وبعضها يُرجع قيمة جديدة ويتركها دون مساس (<code dir=\"ltr\">slice</code> و<code dir=\"ltr\">map</code> و<code dir=\"ltr\">filter</code>).","<code dir=\"ltr\">map</code> تُرجع مصفوفة جديدة بالطول نفسه وقد حُوّل كل عنصر فيها؛ و<code dir=\"ltr\">filter</code> تُرجع مصفوفة جديدة فيها العناصر التي تجتاز الاختبار فقط.","<code dir=\"ltr\">find</code> تُرجع أول عنصر مطابق أو <code dir=\"ltr\">undefined</code>؛ و<code dir=\"ltr\">some</code> و<code dir=\"ltr\">every</code> تجيبان عن أسئلة نعم/لا حول القائمة كلها."],"further":[{"title":"Array (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array"},{"title":"Array.prototype.map() (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map"},{"title":"Array.prototype.filter() (MDN)","url":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter"}],"quiz":[{"q":"<p>ماذا يطبع هذا الكود؟</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> amounts</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">];</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">amounts.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">push</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">270</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(amounts.</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">length</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span></code></pre></div>\n","options":[{"text":"يرمي TypeError، لأن <code dir=\"ltr\">amounts</code> مُصرَّح بها بـ <code dir=\"ltr\">const</code>.","why":"<code dir=\"ltr\">const</code> تمنع فقط توجيه الاسم إلى قيمة أخرى. أما <code dir=\"ltr\">push</code> فتغيّر المصفوفة التي يشير إليها الاسم أصلًا، وهذا مسموح."},{"text":"<code dir=\"ltr\">3</code>","why":"صحيح. <code dir=\"ltr\">push</code> تضيف 270 إلى نهاية المصفوفة نفسها، فيصبح فيها ثلاثة عناصر."},{"text":"<code dir=\"ltr\">2</code>","why":"<code dir=\"ltr\">push</code> تعدّل المصفوفة في مكانها؛ ولا تُرجع نسخة وتترك الأصلية كما هي."}],"answer":1},{"q":"<p><code dir=\"ltr\">const amounts = [450, -300, 1220];</code> ماذا تُرجع <code dir=\"ltr\">amounts.find((a) =&gt; a &gt; 5000)</code>؟</p>","options":[{"text":"<code dir=\"ltr\">[]</code>","why":"المصفوفة الفارغة هي ما تُرجعه <code dir=\"ltr\">filter</code> حين لا يطابق شيء. أما <code dir=\"ltr\">find</code> فتُرجع عنصرًا واحدًا أو لا شيء."},{"text":"<code dir=\"ltr\">-1</code>","why":"<code dir=\"ltr\">-1</code> هي ما تُرجعه <code dir=\"ltr\">findIndex</code> و<code dir=\"ltr\">indexOf</code> للتعبير عن “غير موجود”. أما <code dir=\"ltr\">find</code> فتُرجع العنصر نفسه."},{"text":"<code dir=\"ltr\">undefined</code>","why":"صحيح. <code dir=\"ltr\">find</code> تُرجع أول عنصر يجتاز الاختبار، و<code dir=\"ltr\">undefined</code> حين لا يجتازه أي عنصر."},{"text":"<code dir=\"ltr\">false</code>","why":"الإجابة المنطقية تأتي من <code dir=\"ltr\">some</code> أو <code dir=\"ltr\">every</code>. أما <code dir=\"ltr\">find</code> فتعطيك العنصر المطابق."}],"answer":2},{"q":"<p>ماذا يطبع هذا الكود؟</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> out</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">450</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1220</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">map</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">c</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  c </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">/</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 100</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">});</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(out);</span></span></code></pre></div>\n","options":[{"text":"<code dir=\"ltr\">[undefined, undefined]</code>","why":"صحيح. للـ callback أقواس معقوفة لكن دون <code dir=\"ltr\">return</code>، فيُرجع <code dir=\"ltr\">undefined</code> لكل عنصر، وتجمع <code dir=\"ltr\">map</code> هذه القيم."},{"text":"<code dir=\"ltr\">[4.5, 12.2]</code>","why":"هذا يتطلّب <code dir=\"ltr\">(c) =&gt; c / 100</code> أو <code dir=\"ltr\">return</code> صريحة داخل الأقواس."},{"text":"<code dir=\"ltr\">[450, 1220]</code>","why":"<code dir=\"ltr\">map</code> تبني نتيجتها دائمًا مما يُرجعه الـ callback، لا من العناصر الأصلية أبدًا."}],"answer":0},{"q":"<p>تحتاج إلى معرفة إن كان لكل مصروف في القائمة فئة. أيّ دالة تناسب؟</p>","options":[{"text":"<code dir=\"ltr\">filter</code>","why":"<code dir=\"ltr\">filter</code> ستعطيك مصفوفة جديدة، وستظل مضطرًا إلى مقارنة الأطوال. أما <code dir=\"ltr\">every</code> فتجيب عن السؤال مباشرة."},{"text":"<code dir=\"ltr\">some</code>","why":"<code dir=\"ltr\">some</code> تكون صحيحة إن اجتاز عنصر واحد على الأقل. وأنت تحتاج أن تجتاز العناصر كلها."},{"text":"<code dir=\"ltr\">every</code>","why":"صحيح. <code dir=\"ltr\">every</code> تُرجع true فقط إن اجتاز الاختبار جميع العناصر، وتتوقّف عند أول فشل."},{"text":"<code dir=\"ltr\">map</code>","why":"<code dir=\"ltr\">map</code> تحوّل العناصر؛ ولا تجيب عن سؤال نعم/لا حول القائمة."}],"answer":2}],"exercise":{"kind":"web","mode":"js","starter":{"js":"const amounts = [450, -300, 12000, 1220, -50, 15000];\nconst formatMoney = (cents) => `$${(cents / 100).toFixed(2)}`;\n\n// Use array methods, not for loops, and never change the array you receive.\n\n// Only the positive amounts\nfunction spendingOnly(amounts) {\n  return amounts;\n}\n\n// Every amount formatted with formatMoney\nfunction formatAll(amounts) {\n}\n\n// The first amount of 10000 cents or more, or undefined\nfunction firstBig(amounts) {\n}\n\n// true if any amount is negative\nfunction hasRefund(amounts) {\n  return false;\n}\n\nconsole.log(spendingOnly(amounts), formatAll(amounts));\n"},"solution":{"js":"const amounts = [450, -300, 12000, 1220, -50, 15000];\nconst formatMoney = (cents) => `$${(cents / 100).toFixed(2)}`;\n\nfunction spendingOnly(amounts) {\n  return amounts.filter((a) => a > 0);\n}\n\nfunction formatAll(amounts) {\n  return amounts.map(formatMoney);\n}\n\nfunction firstBig(amounts) {\n  return amounts.find((a) => a >= 10000);\n}\n\nfunction hasRefund(amounts) {\n  return amounts.some((a) => a < 0);\n}\n\nconsole.log(spendingOnly(amounts), formatAll(amounts));\n"},"checks":[{"id":"spending","test":"const arr = [450, -300, 12000, 1220, -50];\nconst out = spendingOnly(arr);\nreturn Array.isArray(out) && out.join() === '450,12000,1220' && arr.length === 5;\n"},{"id":"format","test":"const out = formatAll([450, -300, 5]);\nreturn Array.isArray(out) && out.join('|') === '$4.50|$-3.00|$0.05';\n"},{"id":"first-big","test":"return firstBig([450, 12000, 15000]) === 12000 && firstBig([10000]) === 10000 && firstBig([1, 2]) === undefined;\n"},{"id":"refund","test":"return hasRefund([450, -1]) === true && hasRefund([450, 0]) === false && hasRefund([]) === false;\n"},{"id":"no-mutation","test":"const arr = [450, -300, 12000];\nspendingOnly(arr); formatAll(arr); firstBig(arr); hasRefund(arr);\nreturn arr.join() === '450,-300,12000';\n"}],"title":"اطرح أسئلة على قائمة","prompt":"<p>أكمل أربع دوال باستخدام دوال المصفوفات بدلًا من حلقات <code dir=\"ltr\">for</code>. ولا يجوز لأيّ منها أن تغيّر المصفوفة التي تستلمها.</p>\n<ul>\n<li><code dir=\"ltr\">spendingOnly(amounts)</code> تُرجع مصفوفة جديدة فيها المبالغ الموجبة فقط.</li>\n<li><code dir=\"ltr\">formatAll(amounts)</code> تُرجع كل المبالغ منسّقة بالدالة المعطاة <code dir=\"ltr\">formatMoney</code>.</li>\n<li><code dir=\"ltr\">firstBig(amounts)</code> تُرجع أول مبلغ قيمته 10000 سنت أو أكثر، أو <code dir=\"ltr\">undefined</code>.</li>\n<li><code dir=\"ltr\">hasRefund(amounts)</code> تُرجع <code dir=\"ltr\">true</code> إن كان أي مبلغ سالبًا.</li>\n</ul>\n","hints":["طابِق كل سؤال مع دالة: الاحتفاظ ببعض العناصر هو <code dir=\"ltr\">filter</code>، وتحويل كل عنصر هو <code dir=\"ltr\">map</code>، وأول تطابق هو <code dir=\"ltr\">find</code>، وأي تطابق هو <code dir=\"ltr\">some</code>.","يمكنك تمرير <code dir=\"ltr\">formatMoney</code> مباشرة إلى <code dir=\"ltr\">map</code>، دون أقواس: <code dir=\"ltr\">amounts.map(formatMoney)</code>.","كل جسم سطر واحد، مثل <code dir=\"ltr\">return amounts.filter((a) =&gt; a &gt; 0);</code>."],"explanation":"<p>كل سؤال يقابله دالة واحدة. <code dir=\"ltr\">filter</code> تحتفظ بالعناصر التي يُرجع لها الـ callback شيئًا truthy، و<code dir=\"ltr\">map</code> تبني مصفوفة بالطول نفسه من القيم التي يُرجعها الـ callback، و<code dir=\"ltr\">find</code> تُرجع العنصر المطابق الأول نفسه (أو <code dir=\"ltr\">undefined</code>)، و<code dir=\"ltr\">some</code> تُرجع <code dir=\"ltr\">true</code> بمجرّد أن يجتاز عنصر واحد. ولا تعدّل أيّ من هذه الدوال في المكان، لذلك تبقى مصفوفة المُستدعي كما كانت تمامًا. وتمرير <code dir=\"ltr\">formatMoney</code> مباشرة إلى <code dir=\"ltr\">map</code> ينجح لأن <code dir=\"ltr\">map</code> تستدعيها مع كل عنصر بصفته الوسيط الأول.</p>\n","checkLabels":{"spending":"<code dir=\"ltr\">spendingOnly</code> تُرجع المبالغ الموجبة فقط","format":"<code dir=\"ltr\">formatAll</code> تنسّق كل المبالغ","first-big":"<code dir=\"ltr\">firstBig</code> تُرجع أول مبلغ قيمته 10000 أو أكثر، أو undefined","refund":"<code dir=\"ltr\">hasRefund</code> تكتشف المبالغ السالبة","no-mutation":"لا تغيّر أيّ من الدوال مصفوفة المدخلات"}},"words":599,"readMinutes":4}