سائق القطار

سائق القطار

تمرين تعلّمي

مقدمة

تحتوي JavaScript على عامل مدمج هو ... يسهّل التعامل مع عدد غير محدد من العناصر. وبحسب السياق، يُسمى إما عامل الباقي وإما عامل النشر.

عامل الباقي

عناصر الباقي

عندما تظهر ... على الجانب الأيسر من إسناد، تُعرف هذه النقاط الثلاث باسم عامل rest. ويُسمّى اجتماع النقاط الثلاث مع اسم متغير عنصر الباقي. وهو يجمع صفرًا أو أكثر من القيم، ويخزّنها في مصفوفة واحدة.

const [a, b, ...everythingElse] = [0, 1, 1, 2, 3, 5, 8];
a;
// => 0
b;
// => 1
everythingElse;
// => [1, 2, 3, 5, 8]

لاحظ أنه في JavaScript، بخلاف بعض اللغات الأخرى، لا يمكن لعنصر rest أن يحمل فاصلة أخيرة. بل يجب أن يكون العنصر الأخير في إسناد تفكيكي. والمثال التالي يُطلق خطأ SyntaxError:

const [...items, last] = [2, 4, 8, 16]

خصائص الباقي

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

const { street, ...address } = {
  street: 'Platz der Republik 1',
  postalCode: '11011',
  city: 'Berlin',
};
street;
// => 'Platz der Republik 1'
address;
// => {postalCode: '11011', city: 'Berlin'}

معاملات الباقي

عندما تظهر ... في تعريف دالة بجانب وسيطها الأخير، يُسمى ذلك المعامل معامل الباقي. وهو يسمح للدالة بقبول عدد غير محدد من الوسائط في صورة مصفوفة.

function concat(...strings) {
  return strings.join(' ');
}
concat('one');
// => 'one'
concat('one', 'two', 'three');
// => 'one two three'

النشر

عناصر النشر

عندما تظهر ... على الجانب الأيمن من إسناد، تُعرف باسم عامل spread. وهي توسّع المصفوفة إلى قائمة من العناصر. وبخلاف عنصر الباقي، يمكن أن تظهر في أي موضع من تعبير مصفوفة حرفي، ويمكن أن يوجد أكثر من واحد.

const oneToFive = [1, 2, 3, 4, 5];
const oneToTen = [...oneToFive, 6, 7, 8, 9, 10];
oneToTen;
// => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const woow = ['A', ...oneToFive, 'B', 'C', 'D', 'E', ...oneToFive, 42];
woow;
// =>  ["A", 1, 2, 3, 4, 5, "B", "C", "D", "E", 1, 2, 3, 4, 5, 42]

خصائص النشر

على غرار المصفوفات، يمكن أيضًا استخدام عامل النشر لنسخ الخصائص من كائن إلى آخر.

let address = {
  postalCode: '11011',
  city: 'Berlin',
};
address = { ...address, country: 'Germany' };
// => {
//   postalCode: '11011',
//   city: 'Berlin',
//   country: 'Germany',
// }

التعليمات

صديقك لينوس سائق قطارات يقود قطارات الشحن بين المدن. وهو بارع جدًا في التعامل مع القطارات، لكنه ليس بارعًا في التعامل مع الخدمات اللوجستية أو الحواسيب. ويرغب في الاستعانة بمساعدتك البرمجية لتنظيم تفاصيل القطارات وتصحيح الأخطاء في بيانات المسارات.

Note

للتدريب، استخدم عامل rest أو spread لحل كل مهمة من المهام التالية.

1. أنشئ مصفوفة بكل العربات

كان صديقك يتابع معرّف كل عربة (ID)، لكنه لا يعرف أبدًا عدد العربات التي سيتعيّن على النظام معالجتها في أي لحظة. سيكون من الأسهل بكثير لبقية برنامج اللوجستيات أن تُجمَّع هذه البيانات في array موحّد.

نفّذ دالة getListOfWagons تقبل عددًا غير محدّد من معرّفات العربات، وهي معرّفات كل عربة. سيكون كل معرّف عددًا صحيحًا موجبًا. وعلى الدالة بعد ذلك أن تُرجع المعرّفات المعطاة في array واحد.

getListOfWagons(1, 7, 12, 3, 14, 8, 5);
// => [1, 7, 12, 3, 14, 8, 5]

2. انقل أول عنصرين إلى نهاية المصفوفة

في هذه المرحلة، بدأت تتكوّن لديك فكرة عن البيانات وعن كيفية استخدامها في برنامج اللوجستيات. يخصّص نظام المعرّفات دائمًا للقاطرة المعرّف 1، بينما تُخصَّص بقية عربات القطار معرّفًا عشوائيًا مختارًا أكبر من 1.

اضطر صديقك إلى ربط عربتين جديدتين بالقطار، لكنه نسي تحديث النظام! الآن، يجب نقل أول عربتين في array القطار إلى النهاية، وإلا فسيختل ترتيب كل شيء.

سيكون لينوس ممتنًا لك حقًا لأنك صحّحت أخطاءه.

نفّذ دالة fixListOfWagons تقبل مصفوفة تحتوي على معرّف كل عربة. وهي تُرجع، عبر الكلمة المفتاحية return، array يُنقل فيه أول عنصرين إلى نهاية array بحيث تكون القاطرة في المقدمة.

eachWagonsID = [2, 5, 1, 7, 4, 12, 6, 3, 13];
fixListOfWagons(eachWagonsID);
// => [1, 7, 4,  12, 6, 3, 13, 2, 5]

3. أضف القيم المفقودة

أوه. يبدو أن بعض العربات قد ضاعت.

لحسن الحظ، وجد صديقك للتو array آخر يبدو أنه يحتوي على معرّفات العربات المفقودة، ويرغب في أن تضيفها إلى array معرّفات العربات الرئيسي. وكل ما يتذكّره هو أن القيم المفقودة يجب أن تُوضع مباشرة بعد القاطرة المحدّدة.

بناءً على هذه المعلومات الجديدة، اكتب دالة تُسمّى correctListOfWagons تأخذ مصفوفتين تحتويان على معرّفات كل عربة كوسائط. يجب إضافة معرّفات العربات الموجودة في array الثاني إلى array الأول مباشرة بعد القاطرة (ID 1).

eachWagonsID = [1, 5, 20, 7, 4, 8];
missingWagons = [3, 17, 6, 15];
correctListOfWagons(eachWagonsID, missingWagons);
// => [1, 3, 17, 6, 15, 5, 20, 7, 4, 8]

4. وسّع معلومات المسارات

الآن بعد أن أصبحت جميع بيانات العربات صحيحة، يرغب صديقك في أن تحدّث معلومات المسارات في النظام. أُنشئت معلومات المسارات الأولية على شكل object، ويرغب صديقك في أن تحدّثها بالإضافة المقدَّمة. كل مسار يتطلب معلومات مختلفة قليلًا، لذلك يفضّل صديقك حقًا حلاً عامًا.

نفّذ دالة extendRouteInformation تقبل objects اثنين. يحتوي object الأول على المدن التي يتنقّل بينها مسار القطار.

ويحتوي object الثاني على تفاصيل أخرى للمسار مثل سرعة القطار أو طوله. وعلى الدالة أن تُرجع object موحّدًا يحوي جميع معلومات المسارات.

Note

يمكن أن يحتوي المتغير moreRouteInformation على خصائص مختلفة.

route = { from: 'Berlin', to: 'Hamburg' };
moreRouteInformation = { length: '100', speed: '50' };
extendRouteInformation(route, moreRouteInformation);
// => {from: "Berlin", to: "Hamburg", length: "100", speed: "50"}

5. افصل وقت الوصول عن معلومات المسارات

لاحظ صديقك أنه لا يحتاج وقت الوصول ضمن معلومات المسارات. لذلك يرغب صديقك في أن تفصل وقت الوصول عن معلومات المسارات.

نفّذ دالة separateTimeOfArrival تقبل كائنًا يحتوي على معلومات المسارات. وعلى الدالة أن تُرجع مصفوفة يكون فيها العنصر الأول وقت الوصول، والعنصر الثاني كائنًا يحوي معلومات المسارات دون وقت الوصول.

routeInformation = {
  from: 'Berlin',
  to: 'Hamburg',
  length: '100',
  timeOfArrival: '10:10',
};
separateTimeOfArrival(routeInformation);
// => ["10:10", {from: "Berlin", to: "Hamburg", length: "100"}]
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
JavaScript Exercism

مستعد لبدء سائق القطار؟

سجّل في Exercism لتتعلّم وتتقن JavaScript عبر 37 مفهومًا159 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.