【JavaScript】配列要素の削除!shiftとpopで先頭・末尾を操作する方法

目次

概要

配列データを整理する際、「一番古いデータを捨てたい(先頭削除)」や「直前の追加を取り消したい(末尾削除)」といった操作は頻繁に発生します。

JavaScriptでは、shift メソッドと pop メソッドを使うことで、これらの操作を直感的かつ高速に行うことができます。本記事では、これらのメソッドの挙動と、戻り値(削除された中身)の活用方法を解説します。

仕様(入出力)

メソッド動作削除位置戻り値
shift()配列の 先頭 の要素を削除する先頭 (インデックス0)削除された要素の値
(配列が空の場合は undefined)
pop()配列の 末尾 の要素を削除する末尾 (最後のインデックス)削除された要素の値
(配列が空の場合は undefined)
  • 副作用: 元の配列自体が変更され、長さ(length)が1減ります(破壊的メソッド)。

基本の使い方

1. 先頭を削除する (shift)

行列の先頭から人を案内するように、一番古いデータを取り出して削除します。

const fruits = ['Apple', 'Orange', 'Banana'];

// 先頭の 'Apple' を削除し、変数に格納
const firstItem = fruits.shift();

console.log(firstItem); // "Apple"
console.log(fruits);    // ["Orange", "Banana"]

2. 末尾を削除する (pop)

積み上げた荷物の一番上を下ろすように、最後に追加されたデータを取り出して削除します。

const colors = ['Red', 'Green', 'Blue'];

// 末尾の 'Blue' を削除し、変数に格納
const lastItem = colors.pop();

console.log(lastItem); // "Blue"
console.log(colors);   // ["Red", "Green"]

3. 空の配列で実行した場合

エラーにはならず、undefined が返されます。

const emptyArray = [];
const result = emptyArray.pop();

console.log(result); // undefined

コード全文(HTML / JavaScript)

通知センターを模したデモを作成します。

「古い通知を既読にする(shift)」操作と、「間違って送った最新通知を取り消す(pop)」操作を実装し、それぞれの挙動の違いを確認します。

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Notification Manager</title>
    <style>
        body { font-family: sans-serif; padding: 20px; }
        .container {
            max-width: 400px;
            border: 1px solid #ccc;
            padding: 20px;
            border-radius: 8px;
            background-color: #f9f9f9;
        }
        .btn-group {
            margin-bottom: 20px;
            display: flex;
            gap: 10px;
        }
        button {
            padding: 8px 12px;
            cursor: pointer;
            border: none;
            border-radius: 4px;
            color: white;
            font-size: 0.9rem;
        }
        .btn-process { background-color: #2196F3; } /* 青: shift */
        .btn-undo { background-color: #F44336; }    /* 赤: pop */
        
        .list-area {
            background: white;
            border: 1px solid #ddd;
            min-height: 100px;
            padding: 10px;
            list-style: none;
            margin: 0;
        }
        .list-item {
            padding: 8px;
            border-bottom: 1px solid #eee;
        }
        .message-box {
            margin-top: 15px;
            padding: 10px;
            background-color: #e0f7fa;
            color: #006064;
            border-radius: 4px;
            font-size: 0.9em;
            display: none; /* 初期状態は非表示 */
        }
    </style>
</head>
<body>

<div class="container">
    <h3>受信トレイ (Queue & Stack)</h3>
    
    <div class="btn-group">
        <button id="btn-shift" class="btn-process">処理して削除 (shift)</button>
        <button id="btn-pop" class="btn-undo">送信取り消し (pop)</button>
    </div>

    <ul id="notification-list" class="list-area">
        </ul>

    <div id="action-log" class="message-box"></div>
</div>

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

JavaScript

/**
 * 通知管理システム
 * shiftとpopの使い分けデモ
 */

// 初期の通知データ
const notifications = [
    'User1: こんにちは',
    'System: アップデート完了',
    'User2: 会議の件について',
    'Admin: メンテナンス予告'
];

// DOM要素の取得
const listElement = document.getElementById('notification-list');
const logElement = document.getElementById('action-log');

/**
 * リストを再描画する関数
 */
const renderList = () => {
    listElement.innerHTML = '';
    
    if (notifications.length === 0) {
        listElement.innerHTML = '<li style="color:#999; padding:8px;">通知はありません</li>';
        return;
    }

    notifications.forEach((note) => {
        const li = document.createElement('li');
        li.className = 'list-item';
        li.textContent = note;
        listElement.appendChild(li);
    });
};

/**
 * 操作ログを表示する関数
 * @param {string} text - メッセージ
 */
const showLog = (text) => {
    logElement.textContent = text;
    logElement.style.display = 'block';
    
    // 3秒後に消す
    setTimeout(() => {
        logElement.style.display = 'none';
    }, 3000);
};

// 初期表示
renderList();

// ---------------------------------------------------------
// イベントハンドラの設定
// ---------------------------------------------------------

// 1. shiftボタン: 先頭(一番古い通知)を処理して削除
document.getElementById('btn-shift').addEventListener('click', () => {
    // 配列が空でないか確認
    if (notifications.length === 0) return;

    // ★ shift() の実行
    const removedItem = notifications.shift();
    
    renderList();
    showLog(`「${removedItem}」を処理しました。(残り${notifications.length}件)`);
});

// 2. popボタン: 末尾(最新の通知)を取り消して削除
document.getElementById('btn-pop').addEventListener('click', () => {
    if (notifications.length === 0) return;

    // ★ pop() の実行
    const removedItem = notifications.pop();
    
    renderList();
    showLog(`「${removedItem}」を取り消しました。(残り${notifications.length}件)`);
});

カスタムポイント

  • 戻り値の利用:コード例では削除した値 (removedItem) をログ表示に使っています。これを「ゴミ箱配列」に移動させたり、Undo機能のために履歴配列に保存したりすることで、高度なアプリを作成できます。
  • ボタンの無効化:配列の長さが0になった時点で、削除ボタンに disabled 属性を付与する制御を入れると、UIとしてより親切になります。

注意点

  1. 破壊的メソッドであるshiftpop も元の配列を書き換えます。「元のデータは残したまま、削除後の新しい配列が欲しい」場合は、slicefilter を使用する必要があります。
  2. shift のパフォーマンス要素追加の unshift と同様、shift も配列内の全要素のインデックスを前に詰める処理が発生するため、要素数が非常に多い場合(数万件以上)は処理が重くなる可能性があります。
  3. 空配列での戻り値空の配列に対して実行すると undefined が返ります。削除した値を使って何か処理をする場合は、必ず if (value !== undefined) 等のチェックを行ってください。

応用

全要素を削除する

shiftpop をループで回すよりも、長さを0にする方が高速かつシンプルです。

const data = [1, 2, 3, 4, 5];

// 方法1: lengthに0を代入(最速)
data.length = 0; 
console.log(data); // []

// 方法2: 空の配列を再代入(const定義の場合は不可)
// data = [];

まとめ

  • shift(): 先頭を削除する。「待ち行列(キュー)」の処理に使います。
  • pop(): 末尾を削除する。「スタック」や「直前の操作取り消し」に使います。
  • どちらも 削除した値を返す ため、それを変数で受け取って活用することができます。
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

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

目次