نحوه مرتب سازی عناصر آرایه در جاوااسکریپت

آفلاین
user-avatar
عرفان حشمتی
04 شهریور 1400, خواندن در 8 دقیقه

عملیات Sorting عبارت است از فرایند مرتب سازی آیتم‌ها به صورت منظم در یک دنباله که براساس معیارهایی ترتیب داده شده تا بتوانید آنها را به طور موثرتری تجزیه و تحلیل کنید. در این مقاله می‌خواهیم یک روش متداول را که برای مرتب سازی عناصر آرایه به ترتیب حروف الفبا و اعداد استفاده می‌شود، بررسی کنیم. همچنین علاوه بر مثال‌های کلی، یک مثال کاربردی واقعی برای توضیح دادن مفهوم مرتب سازی مقادیر آرایه نیز ارائه خواهیم کرد.

آشنایی با مرتب سازی عناصر آرایه

مرتب سازی به معنای فرایند چیدمان داده‌ها به شکلی معنادار است تا بتوان آنها را به طور موثرتری تجزیه و تحلیل کرد. به عنوان مثال ممکن است بخواهید داده‌ها را در یک ستون برای یافتن رشته "Alex" مرتب کنید یا ممکن است بخواهید داده‌های مربوط به فروش را بر اساس ماه دسته بندی کنید تا بتوانید نمودار عملکرد فروش را بررسی کنید.

مرتب سازی‌ها معمولا در قالب عدد یا حروف الفبا هستند و می‌توانند به ترتیب صعودی (A-Z ، ۰-۹) یا نزولی (Z-A، ۹-۰) باشند.

چرا مرتب سازی داده‌ها مهم است؟

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

توجه: الگوریتم‌های مرتب سازی متفاوتی برای موارد مختلف وجود دارد اما در حیطه مورد بحث این مقاله نیستند.

فکر می‌کنم توضیح به صورت تئوری کافی باشد، بنابراین بیایید وارد قسمت عملی شویم.

مرتب سازی عناصر آرایه به ترتیب حروف الفبا

روش بسیار ساده و آسان برای مرتب سازی عناصر آرایه به صورت الفبایی استفاده از متد Array.prototype.sort است.

مرتب سازی صعودی

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

متد مرتب سازی نیاز به یک پارامتر اختیاری compareFunction(firstEl, secondEl) دارد که ترتیب مرتب سازی را مشخص می‌کند. در صورت حذف، عناصر آرایه به رشته تبدیل می‌شوند، سپس بر اساس مقدار یونیکد هر کاراکتر مرتب می‌گردند.

به مثال زیر نگاهی بیاندازید:

const names = ['Williams', 'James', 'Alex', 'Mason', 'Ella', 'Jackson'];

// Sort the "names" array
names.sort();

console.log(names);
// Output: ["Alex", "Ella", "Jackson", "James", "Mason", "Williams"]

مرتب سازی نزولی

به سادگی می‌توانید عناصر یک آرایه را به ترتیب صعودی مرتب کنید، اما اگر می‌خواهید عناصر را به ترتیب نزولی مرتب کنید، از متد Array.prototype.reverse بعد از مرتب سازی آرایه به صورت زیر استفاده نمایید:

const names = ['Williams', 'James', 'Alex', 'Mason', 'Ella', 'Jackson'];

// Sort the "names" array
names.sort();

// Reverse the "names" array
names.reverse();

console.log(names);
// Output: ["Williams", "Mason", "James", "Jackson", "Ella", "Alex"]

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

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

const names = ['Williams', 'James', 'Alex', 'Mason', 'Ella', 'Jackson'];
	
// Make a shallow copy of the "names" array
const copyOfNames = [...names];

// Sort the "copyOfNames" array
copyOfNames.sort();

console.log(names);
// Output: ["Williams", "James", "Alex", "Mason", "Ella", "Jackson"]

console.log(copyOfNames);
// Output: ["Alex", "Ella", "Jackson", "James", "Mason", "Williams"]

مرتب سازی رشته‌ها با کاراکترهای غیر ASCII

برای مرتب سازی رشته‌هایی با کاراکترهای غیر ASCII یعنی رشته‌هایی حاوی کاراکترهای آکسان دار (e، é، è، a، ä، و ...) و نیز رشته‌هایی از زبان‌های غیر انگلیسی می‌توانید از localeCompare در پارامتر compareFunction متد مرتب سازی استفاده کنید.

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

const items = ['réservé', 'communiqué', 'café', 'adieu', 'éclair'];

items.sort(function (a, b) {
  return a.localeCompare(b);
});

console.log(items);
// Output: ["adieu", "café", "communiqué", "éclair", "réservé"]

توجه: متد localeCompare عددی را برمی‌گرداند که نشان می‌دهد یک رشته مرجع قبل یا بعد از آن آمده یا همان رشته داده شده به ترتیب مرتب سازی است.

مرتب سازی عناصر آرایه به صورت عددی

برای مرتب سازی اعداد می‌توانید از متد Array.prototype.sort استفاده کنید، اما تا زمانی که آیتم‌های آرایه به رشته تبدیل شوند و در واحدهای کد UTF-۱۶ مقایسه شوند، تنها چیزی که نیاز دارید یک ترفند ساده است.

بیایید یک بار آرایهای از اعداد را بدون استفاده از ترفند مرتب کنیم و نتیجه را ببینیم:

const numbers = [۹, ۱, ۸۰, ۱۰۰];

numbers.sort();

console.log(numbers);
// Output: [۱, ۱۰۰, ۸۰, ۹]

آرایه به ترتیب حروف الفبا مرتب شد، بنابراین هر عدد صحیح در واقع به یک نوع رشته تبدیل گردید. سپس هر رشته مقایسه شد، به همین دلیل ۸۰ قبل از ۹ و ۱۰۰ قبل از ۸۰ آمد – رشته‌ها به صورت کاراکتر مقایسه می‌شوند.

راه حل دستیابی به مرتب سازی عددی، انتقال یک تابع مقایسه مانند (a, b) => a - b به متد مرتب سازی به عنوان پارامتر است.

const numbers = [۹, ۱, ۸۰, ۱۰۰];

numbers.sort(function (a, b) {
  return a - b;
});

console.log(numbers);
// Output: [۱, ۹, ۸۰, ۱۰۰]

اگر پارامتر compareFunction برای متد مرتب سازی فراهم شود، همه عناصر آرایه تعریف نشده با توجه به مقدار بازگشتی تابع مقایسه مرتب می‌شوند. فرض کنید a و b دو عنصر در حال مقایسه هستند، پس:

اگر compareFunction(a, b) مقداری بیشتر از صفر را برمی‌گرداند، b را قبل از a مرتب کن و
اگر compareFunction(a, b) مقداری کوچکتر یا مساوی صفر را برمی‌گرداند، a و b را در همان ترتیب خودشان قرار بده.

بنابراین تابع مقایسه می‌تواند چیزی شبیه به کد زیر را داشته باشد:

function compare(a, b) {
  if (a is less than b by some ordering criterion) {
    return -۱;
  }

  if (a is greater than b by the ordering criterion) {
    return ۱;
  }
  // a must be equal to b
  return ۰;
}

مرتب سازی صعودی

برای مرتب سازی آرایه از نظر عددی به ترتیب صعودی، تابع مقایسه  (a, b) => a - b باید تفاوت بین دو عدد را برگرداند.

const numbers = [۸, -۲, ۱۰, ۱۰۰, ۱۹, -۴, -۱۰];

numbers.sort((a, b) => a - b);

console.log(numbers);
// Output: [-۱۰, -۴, -۲, ۸, ۱۰, ۱۹, ۱۰۰]

تابع مقایسه (a, b) => a - b آیتم دوم را از اولی کم می‌کند، اگر آیتم دوم بزرگتر باشد مقدار منفی، اگر آیتم دوم کوچکتر باشد مقدار مثبت و اگر هر دو مورد برابر باشند مقدار صفر را برمی‌گرداند.

مرتب سازی نزولی

مرتب سازی نزولی فقط نیاز به عملگرهای معکوس دارد، بنابراین تابع مقایسه (a, b) => b - a می‌شود.

const numbers = [۸, -۲, ۱۰, ۱۰۰, ۱۹, -۴, -۱۰];

numbers.sort((a, b) => b - a);

console.log(numbers);
// Output: [۱۰۰, ۱۹, ۱۰, ۸, -۲, -۴, -۱۰]

موارد استفاده

آرایه زیر را در نظر بگیرید که هر عنصر آن یک شی و دارای دو خصوصیت نام و نمره است:

const results = [
  { name: 'Edward', score: ۸۷ },
  { name: 'Williams', score: ۵۰ },
  { name: 'Andy', score: ۴۵ },
  { name: 'Ella', score: ۷۵ },
  { name: 'Alex', score: ۶۸ },
  { name: 'Mason', score: ۳۷ }
];

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

آن را امتحان کنید و سپس راه حل را ببینید.

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

بیایید آن را انجام دهیم.

همانطور که در بالا اشاره شد، آرایه‌هایی که عناصر آنها شی هستند را می‌توان با مقایسه مقدار یکی از خصوصیات آنها مرتب کرد. بنابراین بیایید با مرتب سازی آرایه نتایج با توجه به خصوصیت نمره شروع کنیم:

// Make a shallow copy
const resultsSortedAccordingToScore = [...results];
		
// Sort in ascending order
resultsSortedAccordingToScore.sort(function (a, b) {
  return a.score - b.score;
});

console.log(resultsSortedAccordingToScore);
/*
 * (۶) [{…}, {…}, {…}, {…}, {…}, {…}]
 *   ۰: {name: "Mason", score: ۳۷}
 *   ۱: {name: "Andy", score: ۴۵}
 *   ۲: {name: "Williams", score: ۵۰}
 *   ۳: {name: "Alex", score: ۶۸}
 *   ۴: {name: "Ella", score: ۷۵}
 *   ۵: {name: "Edward", score: ۸۷}
 */

همانطور که مشاهده می‌کنید، resultsSortedAccordingToScore با توجه به خصوصیت نمره مرتب شده است.

در مرحله بعد، بیایید آرایه نتایج را با توجه به خصوصیت نام مرتب کنیم:

// Make a shallow copy
const resultsSortedAccordingToName = [...results];

// Sort in ascending order
resultsSortedAccordingToName.sort(function (a, b) {
  let nameA = a.name.toLowerCase();
  let nameB = b.name.toLowerCase();

  if (nameA < nameB) {
    return -۱;
  }

  if (nameA > nameB) {
    return ۱;
  }

  // names must be equal
  return ۰;
});

console.log(resultsSortedAccordingToName);
/*
 * (۶) [{…}, {…}, {…}, {…}, {…}, {…}]
 *   ۰: {name: "Alex", score: ۶۸}
 *   ۱: {name: "Andy", score: ۴۵}
 *   ۲: {name: "Edward", score: ۸۷}
 *   ۳: {name: "Ella", score: ۷۵}
 *   ۴: {name: "Mason", score: ۳۷}
 *   ۵: {name: "Williams", score: ۵۰}
 */

همانطور که خروجی را مشاهده می‌کنید، آرایه با توجه به خصوصیت نام مرتب شده است، اما با کمک یک ترفند کوچک.

در مرحله اول، همه حروف را به حروف کوچک (یا حروف بزرگ) تبدیل کردیم تا مقایسه‌ای بدون توجه به حروف انجام دهیم.

نکته: Alex و alex رشته‌های متفاوتی در نظر گرفته می‌شوند، زیرا a و A دارای مقادیر مختلف یونیکد هستند.

جمع بندی

متد مرتب سازی جاوااسکریپت به طور پیش فرض عناصر یک آرایه را به ترتیب حروف الفبا مرتب می‌کند. مرتب سازی یک آرایه را در محل خود تغییر می‌دهد، به این معنی که متد یک آرایه مرتب شده جدید را بر نمی‌گرداند. برای مرتب سازی آرایه به ترتیب نزولی باید بلافاصله بعد از مرتب سازی آرایه، متد Array.prototype.reverse را فراخوانی کنید.

در این مقاله نحوه مرتب سازی یک آرایه در جاوااسکریپت را با استفاده از متد مرتب سازی به ترتیب صعودی و نزولی و به صورت عددی و الفبایی، بررسی کردیم و در پایان هم یک مثال کاربردی واقعی برای درک بهتر آن ارائه نمودیم.

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

اگر هرگونه سوال یا نظری دارید، می‌توانید در بخش زیر با ما در میان بگذارید.

منبع

چه امتیازی به این مقاله می دید؟
خیلی بد
بد
متوسط
خوب
عالی

دیدگاه‌ها و پرسش‌ها

برای ارسال دیدگاه لازم است، ابتدا وارد سایت شوید.

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

آفلاین
user-avatar
عرفان حشمتی @heshmati74
مهندس معماری سیستم های کامپیوتری، طراح و توسعه دهنده وب سایت
دنبال کردن

گفتگو‌ برنامه نویسان

بخشی برای حل مشکلات برنامه‌نویسی و مباحث پیرامون آن وارد شو