【JavaScript】配列の先頭・末尾へデータを追加する!pushとunshiftの完全ガイド

目次

概要

配列をデータリストとして扱う際、「新しいデータを最後尾に追加する」処理と、「優先データを最前列に割り込ませる」処理は頻繁に使用されます。

JavaScriptでは、push メソッドで末尾への追加、unshift メソッドで先頭への追加を簡単に行うことができます。本記事では、これらを活用して「緊急タスク」と「通常タスク」を振り分けるToDoリストの実装例を紹介します。

仕様(入出力)

メソッド動作追加位置戻り値計算量(目安)
push(item1, ...)要素を配列の 後ろ に追加する末尾追加後の 新しい要素数 (Number)高速 ($O(1)$)
unshift(item1, ...)要素を配列の に追加する先頭追加後の 新しい要素数 (Number)要素数に比例して遅くなる ($O(n)$)
  • 入力: 追加したい要素(複数可、型不問)
  • 出力: 変更後の配列の長さ(length
  • 副作用: 元の配列自体が書き換わります(破壊的メソッド)。

基本の使い方

1. 末尾に追加する (push)

時系列順にログを貯める場合や、通常のリスト作成で使用します。

const stack = ['First', 'Second'];

// 末尾に追加
const newLength = stack.push('Third');

console.log(stack);     // ["First", "Second", "Third"]
console.log(newLength); // 3

2. 先頭に追加する (unshift)

新着メールをリストの一番上に表示する場合などに使用します。

const queue = ['Task B', 'Task C'];

// 先頭に追加(割り込み)
queue.unshift('Task A');

console.log(queue); // ["Task A", "Task B", "Task C"]

コード全文(HTML / JavaScript)

「通常タスク」として末尾に追加するか、「緊急タスク」として先頭に割り込ませるかを選択できる、簡易タスク管理ツールです。

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Task Manager Demo</title>
    <style>
        body { font-family: sans-serif; padding: 20px; }
        .control-panel {
            margin-bottom: 20px;
            padding: 15px;
            background-color: #f4f4f4;
            border-radius: 8px;
        }
        input[type="text"] {
            padding: 8px;
            width: 200px;
            margin-right: 10px;
        }
        button {
            padding: 8px 16px;
            cursor: pointer;
            border: none;
            border-radius: 4px;
            color: white;
            font-weight: bold;
        }
        .btn-normal { background-color: #4CAF50; }
        .btn-urgent { background-color: #F44336; }
        
        /* リストの装飾 */
        #task-list {
            list-style: none;
            padding: 0;
            width: 300px;
        }
        .task-item {
            padding: 10px;
            border-bottom: 1px solid #ddd;
            display: flex;
            align-items: center;
        }
        .task-item::before {
            content: "📌";
            margin-right: 10px;
        }
        .urgent-mark { color: red; font-weight: bold; margin-left: auto; font-size: 0.8em; }
    </style>
</head>
<body>

<div class="control-panel">
    <input type="text" id="task-input" placeholder="タスクを入力...">
    <button id="add-normal" class="btn-normal">通常追加 (push)</button>
    <button id="add-urgent" class="btn-urgent">緊急追加 (unshift)</button>
</div>

<h3>現在のタスクリスト:</h3>
<ul id="task-list">
    </ul>

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

JavaScript

/**
 * タスク管理クラス
 */
class TaskManager {
    constructor() {
        // 初期タスクデータ
        this.tasks = ['メール確認', '進捗報告作成'];
        this.listElement = document.getElementById('task-list');
        this.inputElement = document.getElementById('task-input');
        
        // 初期描画
        this.render();
    }

    /**
     * 通常タスクを追加(末尾へ)
     */
    addNormalTask() {
        const text = this.inputElement.value;
        if (!text) return;

        // 配列の最後に要素を追加
        this.tasks.push(text);
        
        this.clearInput();
        this.render();
    }

    /**
     * 緊急タスクを追加(先頭へ)
     */
    addUrgentTask() {
        const text = this.inputElement.value;
        if (!text) return;

        // 配列の先頭に要素を追加
        // ※視覚的に区別するため、(緊急)という文字列を付与します
        this.tasks.unshift(`${text} (緊急)`);
        
        this.clearInput();
        this.render();
    }

    /**
     * 入力欄をクリア
     */
    clearInput() {
        this.inputElement.value = '';
        this.inputElement.focus();
    }

    /**
     * リストを再描画
     */
    render() {
        // リストを一度クリア
        this.listElement.innerHTML = '';

        // 配列の中身をHTMLとして展開
        this.tasks.forEach(task => {
            const li = document.createElement('li');
            li.className = 'task-item';
            li.textContent = task;
            
            // 緊急タスクの場合はスタイルを変える簡易ロジック
            if (task.includes('(緊急)')) {
                li.style.backgroundColor = '#fff0f0';
                li.style.fontWeight = 'bold';
            }
            
            this.listElement.appendChild(li);
        });
    }
}

// アプリケーションの初期化とイベント設定
const app = new TaskManager();

document.getElementById('add-normal').addEventListener('click', () => {
    app.addNormalTask();
});

document.getElementById('add-urgent').addEventListener('click', () => {
    app.addUrgentTask();
});

カスタムポイント

  • 複数追加への対応:pushunshift はカンマ区切りで複数の引数を渡せます。例: array.push('Task A', 'Task B')
  • スプレッド構文の活用:別の配列を結合して追加したい場合、ES6のスプレッド構文 ... が便利です。array.push(...otherArray) とすることで、配列を展開して要素として追加できます。

注意点

  1. unshift のパフォーマンスpush は末尾に付け足すだけなので高速ですが、unshift は既存の全要素のインデックスを1つずつ後ろにずらす処理が発生するため、要素数が数万件〜と巨大になると処理速度が低下します。大規模データの場合は LinkedList などのデータ構造を検討してください。
  2. 戻り値の勘違いpushunshift の戻り値は「変更された配列自体」ではなく、「新しい要素数(数値)」です。メソッドチェーン(例: arr.push(1).push(2))はできないため注意してください。

応用

ログの保存件数を制限する(FIFOの実装)

push で追加しつつ、一定数を超えたら shift(先頭削除)を行うことで、常に最新のn件だけを保持するリストを作れます。

const maxLogs = 5;
const logs = ['Log1', 'Log2', 'Log3', 'Log4', 'Log5'];

function addLog(newLog) {
    logs.push(newLog); // 末尾に追加
    
    // 最大数を超えたら、一番古いもの(先頭)を削除
    if (logs.length > maxLogs) {
        logs.shift();
    }
}

addLog('Log6');
console.log(logs); // ["Log2", "Log3", "Log4", "Log5", "Log6"] (Log1が消えた)

まとめ

データの順序が重要なアプリケーションにおいて、追加位置をコントロールすることは必須のスキルです。

  • リストの下に追加したい(通常): push()
  • リストの上に追加したい(割り込み): unshift()

この2つを使い分け、ユーザーにとって直感的なデータ表示を実現してください。

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

この記事を書いた人

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

目次