1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

初心者から中級者への一歩!JavaScriptでforループから高階関数へ

Last updated at Posted at 2023-07-26

JavaScriptでは、コードを書く方法の一つとして、forループを用いて配列を操作するというのが一般的です。しかし、JavaScriptは関数型プログラミングの概念を豊富に取り入れており、filter、map、reduce、some、everyといった高階関数を利用することで、より簡潔で宣言的なコードを書くことが可能です。

ここでは、これらの関数を一つずつ見ていき、それぞれが何をするものであるか、またそれらを使うことで得られるメリットを紹介します。

関数名 説明
filter 条件に一致する要素だけを抽出した新しい配列を生成します。
map 配列の全ての要素を変換した結果の新しい配列を生成します。
reduce 配列の全ての要素を単一の値(集約値)に結合します。
some 配列のいずれかの要素が条件を満たすかどうかをチェックします。条件を満たす要素が一つでもあればtrueを返します。
every 配列の全ての要素が条件を満たすかどうかをチェックします。全ての要素が条件を満たせばtrueを返します。

前提として、次のような社員データがあるとします。

const employees = [
  { name: 'Alice', salary: 50000, department: 'Engineering' },
  { name: 'Bob', salary: 60000, department: 'Marketing' },
  { name: 'Charlie', salary: 70000, department: 'Engineering' },
  { name: 'Daniel', salary: 80000, department: 'Marketing' },
  { name: 'Eva', salary: 55000, department: 'Engineering' },
];

filter関数

filterは配列の中から条件に合う要素だけを取り出すための関数です。

たとえば、エンジニアリング部門の社員だけを取り出したいとき、次のようなforループを書く代わりに、

let engineeringEmployees = [];

for(let i = 0; i < employees.length; i++) {
    if(employees[i].department === 'Engineering') {
        engineeringEmployees.push(employees[i]);
    }
}

console.log(engineeringEmployees); 

filter関数を使えば、同じことがもっとシンプルに書けます。

const engineeringEmployees = employees.filter(employee => employee.department === 'Engineering');

console.log(engineeringEmployees); 

このコードは前のコードと同じ結果を得ますが、はるかに読みやすく、バグの発生を防ぎます。

map関数

map関数は配列の全ての要素に同じ操作を適用し、その結果から新しい配列を作成します。

たとえば、全ての社員の名前と給与だけを抽出した新しい配列を作りたいとき、次のようなforループを書く代わりに、

let employeeSummaries = [];

for(let i = 0; i < employees.length; i++) {
    employeeSummaries.push({name: employees[i].name, salary: employees[i].salary});
}

console.log(employeeSummaries); 

map関数を使えば、同じことがはるかにシンプルに書けます。

const employeeSummaries = employees.map(employee => ({name: employee.name, salary: employee.salary}));

console.log(employeeSummaries);

このように、map関数を使うと、コードが読みやすくなり、誤解を防ぐことができます。

reduce関数

reduce関数は配列の全ての要素を単一の値に結合します。

たとえば、全ての社員の給与の合計を求めるとき、次のようなforループを書く代わりに、

let totalSalary = 0;

for (let i = 0; i < employees.length; i++) {
    totalSalary += employees[i].salary;
}

console.log(totalSalary);  

reduce関数を使えば、同じことがはるかにシンプルに書けます。

const totalSalary = employees.reduce((accumulator, employee) => accumulator + employee.salary, 0);

console.log(totalSalary);  

このように、reduce関数はコードを読みやすく、複雑なループや一時的な変数を使用する必要をなくします。

some関数

some関数は、特定の条件を満たす値が配列に1つ以上存在するかを確認します。

たとえば、社員の給与が80000以上の社員が存在するかを確認したいとき、次のようなforループを書く代わりに、

let hasHighlyPaidEmployee = false;

for (let i = 0; i < employees.length; i++) {
  if (employees[i].salary >= 80000) {
    hasHighlyPaidEmployee = true;
    break;
  }
}

console.log(hasHighlyPaidEmployee);

some関数を使えば、同じことがはるかにシンプルに書けます。

const hasHighlyPaidEmployee = employees.some(employee => employee.salary >= 80000);

console.log(hasHighlyPaidEmployee);

some関数を使うことで、ループの途中でbreakするという明示的な操作が不要になり、コードがシンプルで読みやすくなります。

every関数

every関数は、配列の全ての要素が条件を満たすかどうかを確認します。

たとえば、社員の給与が全員50000以上かを確認したいとき、次のようなforループを書く代わりに、。

let areAllEmployeesWellPaid = true;

for (let i = 0; i < employees.length; i++) {
  if (employees[i].salary < 50000) {
    areAllEmployeesWellPaid = false;
    break;
  }
}

console.log(areAllEmployeesWellPaid);

every関数を使えば、同じことがはるかにシンプルに書けます。

const areAllEmployeesWellPaid = employees.every(employee => employee.salary >= 50000);

console.log(areAllEmployeesWellPaid);

some関数と同様に、every関数を使うことで、旧来のコードにおけるbreakの使用が不要になり、より簡潔なコードになります。

filterとmapの連携

これらの関数は単独で使うだけでなく、連携させることでさらにパワフルになります。たとえば、エンジニアリング部門の社員の名前と給与だけを抽出したい場合、filtermapを一緒に使うことができます。

const engineeringSummaries = employees
  .filter(employee => employee.department === 'Engineering')
  .map(employee => ({name: employee.name, salary: employee.salary}));

console.log(engineeringSummaries);

このコードはまずfilterでエンジニアリング部門の社員だけを取り出し、次にmapで名前と給与だけのオブジェクトを作っています。これらの関数を組み合わせることで、データの変換とフィルタリングを一度に行うことができ、コードがより簡潔で可読性が高くなります。

まとめ

JavaScriptのfiltermapreducesomeeveryは非常に強力な関数で、配列操作を行う際にはこれらの関数を積極的に活用することをお勧めします。これらの関数を使うことで、コードが簡潔になり、読みやすくなるだけでなく、バグの発生を防ぐことも可能になります。また、複数の関数を組み合わせることで、より複雑な操作をシンプルに表現することができます。

これらの関数を理解し、使いこなすことで、より効率的で可読性の高いコードを書くことができるようになるでしょう。

以上、この記事はChatGPT-4が以下のプロンプトで書いたものを少し手直ししています。

JavaScriptでは、旧来はforループで書いていたものを、filter, map, reduce, some, every といった関数によって簡潔に、宣言的に書けるようになりました。
それについてMarkDown形式で記事を書いてください。

記事はまず、filter, map, reduce, some, every の簡単な紹介を表形式でまとめ、各関数について、それらの関数を使わないforループによる「以前の書き方」を紹介し、それを各関数を用いた簡潔で宣言的なコードに置き換え、そうすることのメリットを提示してください。記事の最後には filter と mapを組み合わせた例も提示してください。サンプルコードでは数値の配列のようなシンプルなデータではなく、社員レコードのようなものを扱うようにしてください。

1
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?