IT・テクノロジー

【オウル先生の基礎講座】Vol.4「配列操作をマスターしよう」

progmraming

配列の様々な操作方法と実践的なテクニックを紹介

配列ってただのデータの集まりじゃないの?操作方法を覚える必要あるの?
フォックン
フォックン
フォックン、配列はプログラミングで最も頻繁に使うデータ構造の1つだよ!配列操作を極めると、複雑なデータ処理を簡潔に書けるようになるんだ。例えば、ユーザー一覧の絞り込みや、商品リストのソート、売上データの分析など、実際の開発でよく使われるシーンばかりだよ😊
オウル先生
オウル先生

配列の基本概念

配列は順序付けられたデータの集合で、各要素にインデックス(0から始まる番号)でアクセスできます。

// 配列の作成方法
const fruits = ['りんご', 'バナナ', 'みかん'];
const numbers = [1, 2, 3, 4, 5];
const mixed = [1, 'hello', true, {name: 'Alice'}];

// インデックスでのアクセス
console.log(fruits[0]); // 'りんご'
console.log(fruits[1]); // 'バナナ'

基本的な配列操作メソッド

要素の追加・削除

const fruits = ['りんご', 'バナナ'];

// 末尾に追加:push()
fruits.push('みかん');
console.log(fruits); // ['りんご', 'バナナ', 'みかん']

// 先頭に追加:unshift()
fruits.unshift('いちご');
console.log(fruits); // ['いちご', 'りんご', 'バナナ', 'みかん']

// 末尾から削除:pop()
const lastFruit = fruits.pop();
console.log(fruits); // ['いちご', 'りんご', 'バナナ']

// 先頭から削除:shift()
const firstFruit = fruits.shift();
console.log(fruits); // ['りんご', 'バナナ']
push()とpop()、shift()とunshift()は対になってるんだね!
フォックン
フォックン
その通り!スタックとキューのデータ構造の概念につながっているんだ。pushとpopでLIFO(後入先出)、shiftとunshiftでFIFO(先入先出)の動作になるよ。
オウル先生
オウル先生

配列の結合・分割

// 配列の結合:concat()
const fruits1 = ['りんご', 'バナナ'];
const fruits2 = ['みかん', 'ぶどう'];
const allFruits = fruits1.concat(fruits2);
console.log(allFruits); // ['りんご', 'バナナ', 'みかん', 'ぶどう']

// スプレッド演算子を使った結合(ES6+)
const combined = [...fruits1, ...fruits2];

// 配列の一部を抽出:slice()
const selection = allFruits.slice(1, 3);
console.log(selection); // ['バナナ', 'みかん']

// 要素の追加・削除・置換:splice()
const fruits = ['りんご', 'バナナ', 'みかん'];
fruits.splice(1, 1, 'いちご'); // 1番目を削除して'いちご'を挿入
console.log(fruits); // ['りんご', 'いちご', 'みかん']

高度な配列操作メソッド

配列の変換:map()

// 各要素を変換
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// オブジェクトの配列変換
const users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 35 }
];
const userNames = users.map(user => user.name);
console.log(userNames); // ['Alice', 'Bob', 'Charlie']

配列のフィルタリング:filter()

// 条件に合う要素を抽出
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evenNumbers = numbers.filter(n => n % 2 === 0);
console.log(evenNumbers); // [2, 4, 6, 8, 10]

// オブジェクトの配列フィルタリング
const products = [
  { name: 'ノートPC', price: 80000 },
  { name: 'マウス', price: 3000 },
  { name: 'キーボード', price: 5000 }
];
const affordableProducts = products.filter(p => p.price <= 5000);
mapとfilterは配列操作の二大巨頭だよ。例えるなら、mapが「変換装置」、filterが「選別機」って感じかな。データ処理の基本中の基本なので、しっかりマスターしておこう!
オウル先生
オウル先生

配列の集約:reduce()

// 配列の要素を1つの値に集約
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 15

// 複雑な集約処理
const orders = [
  { product: 'Laptop', quantity: 2, price: 1000 },
  { product: 'Mouse', quantity: 5, price: 30 },
  { product: 'Keyboard', quantity: 3, price: 50 }
];

const totalAmount = orders.reduce((total, order) => 
  total + (order.quantity * order.price), 0
);
console.log(totalAmount); // 2300

要素の検索

const fruits = ['りんご', 'バナナ', 'みかん', 'りんご'];

// 要素の存在確認:includes()
console.log(fruits.includes('バナナ')); // true

// 要素の位置検索:indexOf()
console.log(fruits.indexOf('りんご')); // 0(最初の位置)

// 最後の位置検索:lastIndexOf()
console.log(fruits.lastIndexOf('りんご')); // 3

// 条件に合う要素の検索:find()
const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
];
const user = users.find(u => u.id === 2);
console.log(user); // { id: 2, name: 'Bob' }

配列の繰り返し処理

forEach:副作用のある処理

const fruits = ['りんご', 'バナナ', 'みかん'];

// 各要素に対して処理を実行
fruits.forEach((fruit, index) => {
  console.log(`${index}: ${fruit}`);
});

every、some:条件チェック

const ages = [25, 30, 35, 40];

// 全要素が条件を満たすか:every()
const allAdults = ages.every(age => age >= 20);
console.log(allAdults); // true

// いずれかの要素が条件を満たすか:some()
const hasSenior = ages.some(age => age >= 65);
console.log(hasSenior); // false

配列のソート

// 数値配列のソート
const numbers = [3, 1, 4, 1, 5, 9, 2, 6];
numbers.sort((a, b) => a - b); // 昇順
console.log(numbers); // [1, 1, 2, 3, 4, 5, 6, 9]

// 文字列配列のソート
const names = ['Charlie', 'Alice', 'Bob'];
names.sort();
console.log(names); // ['Alice', 'Bob', 'Charlie']

// オブジェクト配列のソート
const students = [
  { name: 'Alice', score: 85 },
  { name: 'Bob', score: 92 },
  { name: 'Charlie', score: 78 }
];
students.sort((a, b) => b.score - a.score); // スコア降順
sort()は元の配列を変更するんだよね!気をつけないと。
フォックン
フォックン
その通り!sort()は破壊的メソッドだから、元の配列を保持したい場合は、先にコピーを作るべきだね。例えば、スプレッドオペレーターを使ってこんな感じで:
オウル先生
オウル先生
const sortedNumbers = [...numbers].sort((a, b) => a - b);

配列のメソッドチェーン

メソッドチェーンを使うと、複数の操作を連続して実行できます:

const products = [
  { name: 'Laptop', price: 80000, category: 'electronics' },
  { name: 'Mouse', price: 3000, category: 'electronics' },
  { name: 'Shirt', price: 5000, category: 'clothing' },
  { name: 'Phone', price: 60000, category: 'electronics' }
];

// 電化製品の平均価格を計算
const averageElectronicsPrice = products
  .filter(p => p.category === 'electronics')
  .map(p => p.price)
  .reduce((sum, price, _, arr) => sum + price / arr.length, 0);

console.log(averageElectronicsPrice); // 47666.67

実践的な配列操作パターン

ユニークな要素の抽出

// 重複を除去
const numbers = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = [...new Set(numbers)];
console.log(uniqueNumbers); // [1, 2, 3, 4, 5]

// オブジェクトの配列で重複除去
const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 1, name: 'Alice' }
];
const uniqueUsers = users.filter((user, index, self) =>
  index === self.findIndex(u => u.id === user.id)
);

配列のグループ化

// グループ化
const products = [
  { name: 'Laptop', category: 'electronics' },
  { name: 'Mouse', category: 'electronics' },
  { name: 'Shirt', category: 'clothing' },
  { name: 'Phone', category: 'electronics' }
];

const groupedByCategory = products.reduce((groups, product) => {
  const category = product.category;
  if (!groups[category]) {
    groups[category] = [];
  }
  groups[category].push(product);
  return groups;
}, {});

console.log(groupedByCategory);
// {
//   electronics: [...],
//   clothing: [...]
// }

2次元配列の操作

// 2次元配列の作成
const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

// 配列フラット化:flat()
const flattened = matrix.flat();
console.log(flattened); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

// 深いネスト配列のフラット化:flat(depth)
const deepNested = [1, [2, [3, [4]]]];
const deepFlattened = deepNested.flat(3);
console.log(deepFlattened); // [1, 2, 3, 4]

パフォーマンス考慮事項

適切なメソッドの選択

// 要素の検索
// ❌ 非効率な方法
const hasBanana = fruits.filter(f => f === 'バナナ').length > 0;

// ✅ 効率的な方法
const hasBanana2 = fruits.includes('バナナ');

// 最初の要素の取得
// ❌ 非効率な方法
const firstUser = users.filter(u => u.role === 'admin')[0];

// ✅ 効率的な方法
const firstUser2 = users.find(u => u.role === 'admin');

実践チャレンジ

以下の問題に挑戦してみましょう:

問題1: ユーザーデータから、年齢が30歳以上のユーザーの名前を抽出し、アルファベット順にソートしてください。

問題2: 注文データから、カテゴリごとの売上合計を算出してください。

問題3: 2つの配列の共通要素を見つけ、新しい配列として返してください。

// 問題1の解答
const users = [
  { name: 'Charlie', age: 25 },
  { name: 'Alice', age: 35 },
  { name: 'Bob', age: 30 },
  { name: 'David', age: 28 }
];

const adultNames = users
  .filter(user => user.age >= 30)
  .map(user => user.name)
  .sort();
console.log(adultNames); // ['Alice', 'Bob']

// 問題2の解答
const orders = [
  { category: 'electronics', amount: 1000 },
  { category: 'clothing', amount: 500 },
  { category: 'electronics', amount: 1500 },
  { category: 'food', amount: 300 }
];

const salesByCategory = orders.reduce((sales, order) => {
  sales[order.category] = (sales[order.category] || 0) + order.amount;
  return sales;
}, {});
console.log(salesByCategory);

// 問題3の解答
const array1 = [1, 2, 3, 4, 5];
const array2 = [4, 5, 6, 7, 8];

const commonElements = array1.filter(item => array2.includes(item));
console.log(commonElements); // [4, 5]

まとめ

配列操作をマスターすることで、データ処理が劇的に効率化されます。特に以下のポイントは重要です:

  1. メソッドの特性理解:破壊的・非破壊的メソッドの区別
  2. 適切なメソッドの選択:状況に応じた最適な手法の選択
  3. メソッドチェーン:読みやすく効率的なコードスタイル
  4. パフォーマンス意識:要素数が多い場合の処理方法
配列操作ってこんなに色んな方法があるんだね!実践で使うのが楽しみ!
フォックン
フォックン
素晴らしい!配列操作は実際の開発プロジェクトで毎日使う基本中の基本なんだ。最初は戸惑うかもしれないけど、これらのメソッドを自由に使えるようになると、プログラミングがもっと楽しくなるよ。次回は関数について学んでいこうね!
オウル先生
オウル先生

次回予告

Vol.5では「関数の使い方をマスターしよう」をテーマに、関数宣言から高度なテクニックまでを詳しく解説します。お楽しみに! 🚀

あわせて読みたい
エラーこそ成長のチャンス!初心者が問題解決能力を爆上げするテクニック
エラーこそ成長のチャンス!初心者が問題解決能力を爆上げするテクニック
あわせて読みたい
【簡単】モチベーションを維持する5つの方法|やる気が続かない悩みを解決!
【簡単】モチベーションを維持する5つの方法|やる気が続かない悩みを解決!
続けて読む
【オウル先生の基礎講座】Vol.5「関数の使い方をマスターしよう」
【オウル先生の基礎講座】Vol.5「関数の使い方をマスターしよう」
ABOUT ME
アウル先生&フォックン
アウル先生&フォックン
ブログライター
オウル先生 フォックンが運営する未経験からのプログラミング上達ガイド! プログラミング学習に興味があるけど、 「どのスクールを選べばいいか分からない…」 「自分に合った学習方法が知りたい…」 「本当にエンジニアになれるか不安…」 そんな悩みをお持ちのあなたへ。 オウル先生とフォックンが、プログラミングスクール選びから学習方法、キャリア形成まで、丁寧にサポートします! 豊富な情報と分かりやすい解説で、あなたのプログラミング学習を成功へと導きます。
記事URLをコピーしました