مرتب سازی اشیا در جاوا اسکریپت
اگر آرایهای از اشیا در زبان برنامهنویسی جاوا اسکریپت دارید که بایستی به شکلی مرتب شوند، خیلی راحت می توانید از تابع جاوا اسکریپت با نام array.sort استفاده کنید.
در شیوه آسان مرتب سازی آرایه به صورت پیش فرض، array.sort هر عنصر در آرایه را که بایستی مرتب شود را به یک رشته تبدیل کرده و آن را با موقعیت کد یونیکد مقایسه می کند.
const foo = [9, 1, 4, 'zebroid', 'afterdeck'];
foo.sort(); // returns [ 1, 4, 9, 'afterdeck', 'zebroid' ]
const bar = [5, 18, 32, new Set, { user: 'Eleanor Roosevelt' }];
bar.sort(); // returns [ 18, 32, 5, { user: 'Eleanor Roosevelt' }, Set {} ]
ممکن است که این پرسش برای شما پیش آمده باشد که چرا 32 پیش از 5 ظاهر شده است. منطقی نیست؟ خب، در واقع منطقی هست. این مساله به این خاطر رخ می دهد که هر عنصر در آرایه ابتدا به یک رشته تبدیل می شود و 32 در ترتیب یونیکد پیش از 5 قرار می گیرد.
array.sort تنها ترتیب آرایه را تغییر می دهد.
const baz = ['My cat ate my homework', 37, 9, 5, 17];
baz.sort(); // baz array is modified
console.log(baz); // shows [ 17, 37, 5, 9, 'My cat ate my homework' ]
برای حل این مساله، می توانید نمونه ای از آرایه را برای ذخیره سازی ایجاد کنید و آن را تغییر دهید. این کار با متدی از آرایه که یک کپی از آرایه مدنظر ما برمیگرداند امکان پذیر است. برای مثال array.slice
const sortedBaz = baz.slice().sort(); // a new instance of the baz array is created and sorted
یا اگر شیوه بهتری را ترجیح می دهید می توانید از عملگر نقطه با همان نتیجه استفاده کنید:
خروجی هر دو مورد یکسان خواهد بود.
const sortedBaz = [...baz].sort(); // a new instance of the baz array is created and sorted
استفاده از array.sort به تنهایی برای مرتب سازی آرایه ای از اشیا خیلی مفید واقع نخواهد شد. خوشبختانه این تابع یک پارامتر دیگر به نام compareFunction قبول می کند که باعث می شود عناصر آرایه مطابق با مقدار برگشی تابع مقایسه ای مرتب شوند.
استفاده از توابع مقایسه ای برای مرتب سازی
اجازه دهید دو عنصر foo و bar را با استفاده از تابع مقایسه ای مقایسه کنیم. مقدار برگشتی تابع مقایسه ای به صورت زیر است:
- 1. کمتر از 0 – foo پیش از bar می آید.
- 2. بزرگتر از 0 – bar پیش از foo می آید
- 3. برابر با 0 – foo و bar با توجه به یکدیگر بدون تغییر می مانند.
اجازه دهید با آرایه ای از اعداد مثالی بزنیم.
const nums = [79, 48, 12, 4];
function compare(a, b) {
if (a > b) return 1;
if (b > a) return -1;
return 0;
}
nums.sort(compare);
// => 4, 12, 48, 79
مثال زیر را به عنوان تفریق a از b در نظر داشته باشید:
function compare(a, b) {
return a - b;
}
تابع بالا را می توان به صورت تابع arrow نیز نوشت:
nums.sort((a, b) => a - b);
چگونه آرایه ای از اشیا را در جاوا اسکریپت مرتب سازی کنیم؟
حالا اجازه دهید ببینیم که چطور می توان آرایه ای از اشیا را در جاوا اسکریپت مرتب کرد.
const singers = [
{ name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },
{ name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 },
{ name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },
{ name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },
];
می توانیم از تابع مقایسه ای زیر برای مرتب سازی این آرایه از خوانندگان مطابق برندشان استفاده کنیم:
function compare(a, b) {
// Use toUpperCase() to ignore character casing
const bandA = a.band.toUpperCase();
const bandB = b.band.toUpperCase();
let comparison = 0;
if (bandA > bandB) {
comparison = 1;
} else if (bandA < bandB) {
comparison = -1;
}
return comparison;
}
singers.sort(compare);
/* returns [
{ name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },
{ name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },
{ name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },
{ name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 }
] */
برای رزرو کردن شیوه مرتب سازی، می توانید مقدار بازگشتی را با استفاده از تابع compare معکوس کنید:
function compare(a, b) {
...
//invert return value by multiplying by -1
return comparison * -1;
}
ساخت تابع پویای مرتب سازی
اجازه دهید تابع مرتب سازی بسازیم که می توانید از آن برای مرتب سازی آرایه ای از اشیا استفاده کنید که مقادیرش رشته یا اعداد می باشد. این تابع دو پارامتر دارد – کلیدی که ما می خواهیم به صورت صعودی یا نزولی مرتبش کنیم.
const singers = [
{ name: 'Steven Tyler', band: 'Aerosmith', born: 1948 },
{ name: 'Karen Carpenter', band: 'The Carpenters', born: 1950 },
{ name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },
{ name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },
];
function compareValues(key, order = 'asc') {
return function innerSort(a, b) {
if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
// property doesn't exist on either object
return 0;
}
const varA = (typeof a[key] === 'string')
? a[key].toUpperCase() : a[key];
const varB = (typeof b[key] === 'string')
? b[key].toUpperCase() : b[key];
let comparison = 0;
if (varA > varB) {
comparison = 1;
} else if (varA < varB) {
comparison = -1;
}
return (
(order === 'desc') ? (comparison * -1) : comparison
);
};
}
و طریقه استفاده از آن به صورت زیر است:
// array is sorted by band, in ascending order by default
singers.sort(compareValues('band'));
// array is sorted by band in descending order
singers.sort(compareValues('band', 'desc'));
// array is sorted by name in ascending order
singers.sort(compareValues('name'));
// array is sorted by date if birth in descending order
singers.sort(compareValues('born', 'desc'));
در کد بالا، متد hasOwnProperty برای بررسی این مساله به کار می رود که خصوصیت مشخص شده در هر شی تعریف شده و از طریق prototype ارث برده نمی شود. اگر در هر دو شی تعریف نشود، تابع مقدار 0 را بازمیگرداند که باعث می شود شیوه مرتب سازی به همان صورتی که بوده باقی بماند (یعنی اشیا با توجه به یکدیگر دست نخورده باقی می مانند).
عملگر typeof نیز برای بررسی نوع داده های مقدار خصوصیت به کار می رود. این عملگر به تابع اجازه می دهد تا روش مناسبی را برای مرتب سازی آرایه تعیین کند. برای مثال، اگر مقدار خصوصیت مشخص شده یک رشته است، متد toUpperCase برای تبدیل تمام کاراکتر به حروف بزرگ به کار می رود، بنابراین بزرگی کوچکی کاراکتر در زمان مرتب سازی نادیده گرفته می شود.
می توانید تابع بالا را طوری تنظیم کنید تا مطابق با دیگر انواع داده و هر نیازی باشد که اسکریپت شما ممکن است داشته باشد.
0 / 5. 0
دیدگاهتان را بنویسید