【JavaScript】条件に合う要素だけを残す!filterメソッドでデータを厳選する方法

目次

概要

配列の中から「レベル50以上のキャラクター」や「スコア80点以上の合格者」など、特定の基準を満たすデータだけを抽出して新しいリストを作成したい場合、filter メソッドが最適です。

for 文や if 文を組み合わせるよりも簡潔に記述でき、元の配列を変更せずに新しい配列を生成する(非破壊的)ため、バグの少ない安全なコードを書くことができます。本記事では、ゲームのギルドメンバーをレベル別に選抜する機能を例に解説します。

仕様(入出力)

filter メソッド

配列の全要素に対してテスト関数を実行し、結果が true となった要素だけを集めて新しい配列を返します。

引数・戻り値説明
callbackFn各要素をテストする関数。
(element, index, array) => 真偽値
戻り値テストに合格した要素からなる 新しい配列
1つも合格しなかった場合は 空の配列 [] を返します。
  • 入力: 元の配列
  • 出力: 抽出された新しい配列
  • 特徴: 元の配列の要素数は変わりません。

基本の使い方

1. 数値を条件で絞り込む

アロー関数を使うと1行で記述できます。

const scores = [45, 90, 30, 85, 60];

// 80点以上だけを抽出
const highScores = scores.filter(score => score >= 80);

console.log(highScores); // [90, 85]

2. コードブロックを使う場合(returnが必要)

処理が複数行になる場合は {} で囲み、明示的に return を記述します。

const numbers = [1, 2, 3, 4, 5, 6];

const oddNumbers = numbers.filter(num => {
    // 奇数かどうかを判定
    return num % 2 !== 0;
});

console.log(oddNumbers); // [1, 3, 5]

コード全文(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>Guild Member Selector</title>
    <style>
        .guild-panel {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            max-width: 500px;
            padding: 20px;
            border: 2px solid #4a3b2c;
            border-radius: 8px;
            background-color: #fdf5e6;
            color: #4a3b2c;
        }
        h3 { margin-top: 0; text-align: center; border-bottom: 2px solid #daa520; padding-bottom: 10px; }
        
        .mission-controls {
            display: flex;
            justify-content: center;
            gap: 10px;
            margin-bottom: 20px;
        }
        .rank-btn {
            padding: 10px 15px;
            border: 1px solid #8b4513;
            background-color: #fff8dc;
            color: #8b4513;
            border-radius: 4px;
            cursor: pointer;
            font-weight: bold;
            transition: all 0.2s;
        }
        .rank-btn:hover, .rank-btn.active {
            background-color: #8b4513;
            color: #fff;
        }
        
        .member-list {
            list-style: none;
            padding: 0;
            margin: 0;
            border-top: 1px solid #ccc;
        }
        .member-card {
            padding: 10px;
            border-bottom: 1px dashed #ccc;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .level-badge {
            background-color: #daa520;
            color: white;
            padding: 3px 8px;
            border-radius: 12px;
            font-size: 0.9em;
        }
    </style>
</head>
<body>

<div class="guild-panel">
    <h3>ギルドメンバー選抜</h3>
    
    <div class="mission-controls">
        <button class="rank-btn active" data-min-level="1">全メンバー</button>
        <button class="rank-btn" data-min-level="30">中級 (Lv30~)</button>
        <button class="rank-btn" data-min-level="50">上級 (Lv50~)</button>
        <button class="rank-btn" data-min-level="80">精鋭 (Lv80~)</button>
    </div>

    <ul id="party-list" class="member-list">
        </ul>
    <p id="party-count" style="text-align: right; font-size: 0.9em; margin-top: 10px;"></p>
</div>

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

JavaScript

/**
 * ギルドメンバー選抜スクリプト
 * filterメソッドを使用したレベル別抽出
 */

// 1. ギルドメンバーリスト(オブジェクトの配列)
// レベル(level)と名前(name)を持つデータ
const guildMembers = [
    { name: "森", level: 85 },
    { name: "小林", level: 12 },
    { name: "大木", level: 45 },
    { name: "中林", level: 60 },
    { name: "小森", level: 92 },
    { name: "林", level: 25 },
    { name: "大森", level: 55 },
    { name: "中木", level: 78 },
    { name: "小木", level: 8 },
    { name: "大林", level: 33 }
];

// DOM要素の取得
const listContainer = document.getElementById('party-list');
const countDisplay = document.getElementById('party-count');
const buttons = document.querySelectorAll('.rank-btn');

/**
 * リストを描画する関数
 * @param {Array} members - 表示対象のメンバー配列
 */
const renderMembers = (members) => {
    listContainer.innerHTML = '';

    if (members.length === 0) {
        listContainer.innerHTML = '<li class="member-card">条件を満たすメンバーはいません。</li>';
        countDisplay.textContent = '参加可能: 0名';
        return;
    }

    members.forEach((member) => {
        const li = document.createElement('li');
        li.className = 'member-card';
        li.innerHTML = `
            <span class="member-name">${member.name}</span>
            <span class="level-badge">Lv.${member.level}</span>
        `;
        listContainer.appendChild(li);
    });

    countDisplay.textContent = `参加可能: ${members.length}名`;
};

/**
 * フィルタリング実行関数
 */
const filterByLevel = (event) => {
    const clickedBtn = event.target;
    
    // 1. ボタンのステータス更新
    buttons.forEach(btn => btn.classList.remove('active'));
    clickedBtn.classList.add('active');

    // 2. data属性から必要レベルを取得
    const requiredLevel = Number(clickedBtn.dataset.minLevel);

    // 3. filterメソッドで抽出
    // メンバーのレベルが必要レベル以上かどうかを判定
    const selectedMembers = guildMembers.filter((member) => {
        return member.level >= requiredLevel;
    });

    // 4. 結果を描画
    renderMembers(selectedMembers);
};

// 初期表示(全員)
renderMembers(guildMembers);

// イベントリスナーの設定
buttons.forEach((btn) => {
    btn.addEventListener('click', filterByLevel);
});

カスタムポイント

  • 範囲指定の追加:「レベル30以上、かつ50未満」のような中間層を抽出したい場合は、条件式を拡張します。JavaScriptlist.filter(member => member.level >= 30 && member.level < 50);
  • 除外設定:特定のメンバー(例: “森”)を除外したい場合は、否定演算子 ! を使用します。JavaScriptlist.filter(member => member.name !== '森');

注意点

  1. 該当なしの挙動find メソッドとは異なり、条件に一致する要素が1つもない場合でも undefined にはならず、空の配列 [] が返されます。データの有無を確認する際は result.length をチェックしてください。
  2. 破壊的ではないfilter は元の配列(guildMembers)を変更しません。フィルタリング結果は必ず新しい変数で受け取る必要があります。

応用

有効なデータのみをクレンジングする

配列の中に nullundefined、あるいは無効なステータスのデータが混ざっている場合、それらを取り除く用途でも活躍します。

const rawData = [100, null, 200, undefined, 0, 300];

// 値が存在するもの(null/undefined以外)だけを残す
const validData = rawData.filter(val => val != null);

console.log(validData); // [100, 200, 0, 300]

まとめ

filter メソッドは、大量のデータから必要なものだけを「ふるい」にかけるための強力なツールです。

  • 抽出: 条件に合うデータをすべて集める。
  • 削除: 条件に合うデータを除外した新しい配列を作る(削除の代用)。
  • 非破壊: 元のデータはそのまま残る。

この3つの特徴を理解し、データの検索や絞り込み機能に活用してください。

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

この記事を書いた人

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

目次