[JavaScript] Mastering Array Sorting with Ascending and Descending Order

目次

Overview

Sorting array data is an essential feature for displaying rankings or organizing lists. While the sort method in JavaScript is powerful, it has a unique specification where elements are compared as strings by default. This often leads to unexpected results when sorting numbers. This article explains how to correctly implement numeric sorting in both ascending and descending order using comparison functions, and how to manage destructive changes to your data.

Specifications (Input/Output)

sort Method

This method reorders the elements of an array.

ArgumentDescriptionReturn Value
compareFn (Optional)A function that defines the sort order. It uses the format (a, b) => numeric_value.The sorted array itself (a reference to the original array).
  • If the return value is negative: a is placed before b.
  • If the return value is positive: b is placed before a.
  • If the return value is 0: The order remains unchanged.

Side Effect: This is a destructive method, meaning the content of the original array is modified.

Note: If the argument is omitted, all elements are converted to strings and compared in dictionary order (Unicode order). For example, “10” will come before “2”.

Basic Usage

1. Numeric Ascending Sort (Smallest to Largest)

Returning a - b in the comparison function ensures that a comes first if it is smaller.

const scores = [80, 5, 100];
scores.sort((a, b) => a - b);
console.log(scores); // [5, 80, 100]

2. Numeric Descending Sort (Largest to Smallest)

Returning b - a in the comparison function ensures that b comes first if it is larger, effectively reversing the order.

const scores = [80, 5, 100];
scores.sort((a, b) => b - a);
console.log(scores); // [100, 80, 5]

Full Code (HTML / JavaScript)

This system manages an internal exam score list. It implements functions to sort the list by “High Score (Descending)” and “Low Score (Ascending).”

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Exam Score Ranking</title>
    <style>
        .ranking-board {
            font-family: 'Helvetica Neue', Arial, sans-serif;
            max-width: 500px;
            margin: 20px auto;
            border: 2px solid #333;
            border-radius: 8px;
            background-color: #fff;
            padding: 20px;
        }
        .controls {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
            justify-content: center;
        }
        button {
            padding: 10px 20px;
            cursor: pointer;
            border: none;
            border-radius: 4px;
            font-weight: bold;
            color: white;
        }
        .btn-asc { background-color: #4CAF50; }
        .btn-desc { background-color: #f44336; }
        
        table {
            width: 100%;
            border-collapse: collapse;
        }
        th, td {
            padding: 12px;
            border-bottom: 1px solid #ddd;
            text-align: left;
        }
        th { background-color: #f2f2f2; }
        .score-col { text-align: right; font-weight: bold; }
    </style>
</head>
<body>

<div class="ranking-board">
    <h3 style="text-align:center;">Internal Exam Results</h3>
    
    <div class="controls">
        <button id="sort-desc" class="btn-desc">Descending (High to Low)</button>
        <button id="sort-asc" class="btn-asc">Ascending (Low to High)</button>
    </div>

    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th class="score-col">Score</th>
            </tr>
        </thead>
        <tbody id="score-list">
            </tbody>
    </table>
</div>

<script src="ranking.js"></script>
</body>
</html>

JavaScript

/**
 * Score Ranking Management Script
 * Handling sort logic using the sort method
 */

// 1. Exam Results Data (Array of Objects)
const examResults = [
    { name: 'Mori', score: 78 },
    { name: 'Kobayashi', score: 92 },
    { name: 'Nakagi', score: 65 },
    { name: 'Obayashi', score: 88 },
    { name: 'Hayashi', score: 78 },
    { name: 'Omori', score: 100 },
    { name: 'Kogi', score: 45 }
];

// DOM elements
const listBody = document.getElementById('score-list');
const btnAsc = document.getElementById('sort-asc');
const btnDesc = document.getElementById('sort-desc');

/**
 * Function to render the table
 */
const renderTable = () => {
    listBody.innerHTML = '';
    
    examResults.forEach((data) => {
        const tr = document.createElement('tr');
        tr.innerHTML = `
            <td>${data.name}</td>
            <td class="score-col">${data.score}</td>
        `;
        listBody.appendChild(tr);
    });
};

/**
 * Ascending Sort (Low to High)
 * Comparison logic: a - b
 */
const sortAscending = () => {
    examResults.sort((a, b) => {
        return a.score - b.score;
    });
    renderTable();
};

/**
 * Descending Sort (High to Low)
 * Comparison logic: b - a
 */
const sortDescending = () => {
    examResults.sort((a, b) => {
        // Using return b.score - a.score is simpler, 
        // but this shows the manual logic for clarity.
        if (a.score < b.score) return 1;  // Move a back
        if (a.score > b.score) return -1; // Move a forward
        return 0;
    });
    renderTable();
};

// Initial display
renderTable();

// Event settings
btnAsc.addEventListener('click', sortAscending);
btnDesc.addEventListener('click', sortDescending);

Custom Points

While the sortDescending function in the example uses an if statement for clarity, you can achieve the same result for numeric comparisons with a single line: return b.score - a.score;. If you need to sort names or strings in Japanese, standard comparison operators might not yield expected results. In such cases, using a.name.localeCompare(b.name, 'ja') allows for dictionary-order sorting that is appropriate for the Japanese language environment.

Important Notes

The sort method is destructive, meaning it directly modifies the original array. If you need to preserve the original order of the data, you should create a copy before sorting using the spread syntax like [...examResults].sort(...) or use the newer non-destructive method toSorted(). Additionally, remember that calling array.sort() without a comparison function converts numbers to strings. This results in “10” being placed before “2” because the character code for “1” is lower than that of “2,” making a comparison function mandatory for numeric data.

Advanced Usage

Sorting by Multiple Conditions

This example shows how to implement a complex sort, such as “sort by score in descending order, and if scores are equal, sort by name in ascending order.”

examResults.sort((a, b) => {
    // 1. Compare by score (Descending)
    if (a.score !== b.score) {
        return b.score - a.score;
    }
    
    // 2. If scores are equal, compare by name (Ascending)
    return a.name.localeCompare(b.name, 'ja');
});

Summary

Sorting arrays is a fundamental process for data visualization and management. When handling numbers, it is critical to always provide a comparison function like (a, b) => a - b for ascending or b - a for descending order. Being mindful of the method’s side effects on the original array will help you avoid bugs and ensure that your data remains consistent throughout your application.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次