مسیرها
/
JavaScript
JavaScript
/
تمرین‌ها
/
افسون‌های دگرگون‌ساز الیز
افسون‌های دگرگون‌ساز الیز

افسون‌های دگرگون‌ساز الیز

تمرین یادگیری

مقدمه

در JavaScript، کلاس Array روش‌های داخلی قدرتمند زیادی برای تبدیل آرایه‌ها دارد. این روش‌ها تبدیل یک آرایه به آرایه‌ی دیگر را بسیار ساده‌تر از آن می‌کنند که در غیر این صورت با یک حلقه‌ی For ساده یا دستکاری مستقیم‌تر ممکن بود.

برخی از این روش‌ها خالص هستند، یعنی آرایه‌ی اصلی را تغییر نمی‌دهند و به‌جای آن یک آرایه‌ی جدید برمی‌گردانند. اما روش‌های دیگر آرایه‌ای را که روی آن فراخوانی می‌شوند دستکاری می‌کنند و آرایه‌ی تغییریافته را برنمی‌گردانند.

در ادامه برخی از پرکاربردترین روش‌های تبدیل آرایه‌ها معرفی می‌شوند. فهرست کامل روش‌های موجود را می‌توانید در مستندات MDN ببینید.

map (خالص)

با تبدیل هر عنصر بر اساس تابعی که به‌عنوان آرگومان داده می‌شود، یک آرایه‌ی جدید بسازید. این توابع callback اغلب به شکل توابع پیکانی نوشته می‌شوند.

let arr = [1, 2, 3, 4];

const newArr = arr.map((value) => value - 1);
console.log(newArr);
// => [0, 1, 2, 3]
console.log(arr);
// => [1, 2, 3, 4]

شایان ذکر است که آرایه‌ی حاصل همیشه همان‌دازه با آرایه‌ی اصلی خواهد بود.

filter (خالص)

با کمک یک تابع فیلترکننده (که اگر عنصر باید نگه داشته شود «درست» و اگر باید حذف شود «غلط» برمی‌گرداند)، آرایه‌ی جدیدی از روی آرایه‌ی فعلی می‌سازد.

let arr = [1, 2, 3, 4];

arr.filter((value) => value % 2 === 0);
// => [2, 4]

reduce (خالص)

آرایه را با استفاده از تابعی که یک انباشتگر و عنصر فعلی آرایه را به‌عنوان پارامتر می‌گیرد، به یک مقدار واحد کاهش می‌دهد. این تابع مشخص می‌کند که عنصر فعلی چگونه باید در انباشتگر ادغام شود و انباشتگری را برمی‌گرداند که در تکرار بعدی استفاده خواهد شد.

let arr = [1, 2, 3, 4];

// Get the sum of elements
arr.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
// => 10

// Classify the numbers by whether they are odd or not
arr.reduce(
  (accumulator, currentValue) => {
    if (currentValue % 2 === 0) {
      accumulator.even.push(currentValue);
    } else {
      accumulator.odd.push(currentValue);
    }

    return accumulator;
  },
  { even: [], odd: [] },
);
// => { even: [2, 4], odd: [1, 3] }

reverse

ترتیب عناصر یک آرایه را برعکس می‌کند.

const arr = [1, 2, 3, 4];

arr.reverse();
// => [4, 3, 2, 1]

این روش آرایه‌ای را که روی آن فراخوانی می‌شود تغییر می‌دهد.

slice (خالص)

با گرفتن ایندکس شروع و پایان، یک زیرآرایه از آرایه‌ی داده‌شده به‌عنوان پارامتر می‌سازد.

عنصر موجود در ایندکس پایان شامل نمی‌شود. همچنین همه‌ی پارامترها اختیاری‌اند: ایندکس شروع به‌طور پیش‌فرض 0 است و ایندکس پایان به‌طور پیش‌فرض طول آرایه.

const arr = [1, 2, 3, 4];

arr.slice(1, 2); // [2]
arr.slice(1); // [2, 3, 4]
// You can also use negative numbers, that represent the indexes
// starting from the end of the array
arr.slice(-2); // [3, 4]

splice

عناصری از یک آرایه را حذف می‌کند، یا جایگزین می‌کند و/یا عناصر جدیدی اضافه می‌کند.

پارامترهای زیر را می‌گیرد:

  • ایندکس عنصری که تغییر آرایه از آنجا شروع می‌شود
  • تعداد عناصری که باید حذف شوند
  • عناصری که باید در آرایه درج شوند (اختیاری)

splice عناصری را که حذف شده‌اند برمی‌گرداند.

const arr = ['1', '2', '5', '6'];

// Insert an element at index 2
arr.splice(2, 0, '3');
console.log(arr);
// => ['1', '2', '3', '5', '6']

// Remove 2 elements, starting at index 3 and insert 2 elements
const removed = arr.splice(3, 2, '4', '5');
console.log(removed);
// => ['5', '6']
console.log(arr);
// => ['1', '2', '3', '4', '5']

// Remove 1 element at index 1
arr.splice(1, 1);
console.log(arr);
// => ['1', '3', '4', '5']

sort

به‌طور پیش‌فرض، sort عناصر یک آرایه را ابتدا با تبدیل آن‌ها به رشته و سپس با اعمال مقایسه‌ی رشته‌ای مرتب می‌کند (به مفهوم مقایسه نگاه کنید). مرتب‌سازی درجا انجام می‌شود، یعنی آرایه‌ی اصلی تغییر می‌کند. sort همچنین همان آرایه‌ی تغییریافته را برمی‌گرداند که اگر بخواهید روش‌های دیگر را به آن زنجیره کنید، راحت است.

const arr = ['c', 'a', 'z', 'b'];
const result = arr.sort();
console.log(result);
// => ['a', 'b', 'c', 'z']
console.log(arr);
// => ['a', 'b', 'c', 'z']

برای سفارشی‌سازی رفتار مرتب‌سازی، می‌توانید یک تابع مقایسه به‌عنوان آرگومان بدهید. خود تابع مقایسه با دو آرگومان فراخوانی می‌شود که همان دو عنصر آرایه هستند. سپس باید موارد زیر را برگرداند:

  • یک عدد منفی اگر آرگومان اول باید قبل از دومی مرتب شود
  • یک عدد مثبت اگر آرگومان اول باید بعد از دومی مرتب شود
  • 0 اگر ترتیب عناصر باید یکسان بماند

در ادامه مثالی می‌بینید از اینکه چگونه می‌توان از یک تابع مقایسه‌ی سفارشی برای مرتب‌سازی آرایه‌ای از شیءها استفاده کرد.

const arr = [
  { name: 'Lydia', age: 7 },
  { name: 'Anne', age: 34 },
  { name: 'Holger', age: 59 },
];

arr.sort((item1, item2) => {
  if (item1.name < item2.name) {
    return -1;
  }
  if (item1.name > item2.name) {
    return 1;
  }
  return 0;
});
// => [ { name: 'Anne', age: 34 }, { name: 'Holger', age: 59 },
// { name: 'Lydia', age: 7 } ]

دستورالعمل‌ها

الیس، جادوگر آینده، آموزش خود را ادامه می‌دهد. یک دسته کارت به او داده می‌شود و او تلاش می‌کند آن دسته را دگرگون کند. او کاری می‌کند که کارت‌های خاصی ظاهر شوند، ناپدید شوند، مقدارشان تغییر کند یا کاملاً جایشان را عوض کنند. برای اینکه کارها آسان‌تر شود، او معمولاً فقط با کارت‌های شمارهی ۱ تا ۱۰ شروع می‌کند، هرچند ممکن است بعضی تردستی‌ها به ساختن کارت‌های بزرگ‌تر منجر شوند.

1. هر کارت را دو برابر کنید

الیس می‌خواهد عدد هر کارت در دسته را دو برابر کند. این کار ممکن است کارت‌هایی بزرگ‌تر از ۱-۱۰ پدید آورد.

const deck = [1, 2, 3, 4, 10];
seeingDouble(deck);
// => [2, 4, 6, 8, 20]

2. از هر ۳ که در دسته پیدا می‌شود، چندین نسخه بسازید

الیس می‌خواهد هر ۳ موجود در دسته را سه‌تایی کند. اگر دسته با یک ۳ شروع شود، پس از این تردستی، به جای آن ۳ اصلی، سه کارت ۳ در دسته خواهد بود.

const deck = [1, 3, 9, 3, 7];
threeOfEachThree(deck);
// => [1, 3, 3, 3, 9, 3, 3, 3, 7]

3. دو کارت را دقیقاً از وسط دسته پیدا کنید

الیس دسته‌ای ده‌کارتی برمی‌دارد و کاری می‌کند که همه‌ی کارت‌ها جز دو کارت وسط ناپدید شوند.

const deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
middleTwo(deck);
// => [5, 6]

4. دو کارت بیرونی دوباره در وسط دسته ظاهر می‌شوند

الیس می‌خواهد کارت‌های بالایی و پایینی دسته را به‌صورت معکوس به وسط منتقل کند.

می‌توانید فرض کنید که تعداد کارت‌های دسته زوج است.

const deck = [1, 2, 3, 5, 6, 10];
sandwichTrick(deck);
// => [2, 3, 10, 1, 5, 6]

5. هر کارتی که ۲ نیست ناپدید می‌شود

شماره‌ی محبوب الیس امروز ۲ است. در این تردستی، هر کارتی که ۲ نباشد از دسته ناپدید می‌شود.

const deck = [1, 2, 3, 4, 10, 2];
twoIsSpecial(deck);
// => [2, 2]

6. دسته‌ی بُرخورده را به دسته‌ای کاملاً مرتب تبدیل کنید

الیس می‌خواهد نشان دهد که در مرتب‌سازی کامل کارت‌ها مهارت دارد، هرچقدر هم که دسته خوب بُر خورده باشد.

const deck = [10, 1, 5, 3, 2, 8, 7];
perfectlyOrdered(deck);
// => [1, 2, 3, 5, 7, 8, 10]

7. دسته را دوباره مرتب کنید

الیس می‌خواهد ترتیب کارت‌های دسته را تغییر دهد. بعد از تردستی، کارتی که الان در بالاست باید در پایین دسته قرار بگیرد. کارت دوم باید یکی مانده به آخر شود و به همین ترتیب.

const deck = [10, 1, 5, 3, 2];
reorder(deck);
// => [2, 3, 5, 1, 10]
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
JavaScript Exercism

آماده‌اید افسون‌های دگرگون‌ساز الیز را شروع کنید؟

در Exercism ثبت‌نام کنید تا JavaScript را همراه با 37 مفهوم159 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.