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の連携
これらの関数は単独で使うだけでなく、連携させることでさらにパワフルになります。たとえば、エンジニアリング部門の社員の名前と給与だけを抽出したい場合、filter
とmap
を一緒に使うことができます。
const engineeringSummaries = employees
.filter(employee => employee.department === 'Engineering')
.map(employee => ({name: employee.name, salary: employee.salary}));
console.log(engineeringSummaries);
このコードはまずfilter
でエンジニアリング部門の社員だけを取り出し、次にmap
で名前と給与だけのオブジェクトを作っています。これらの関数を組み合わせることで、データの変換とフィルタリングを一度に行うことができ、コードがより簡潔で可読性が高くなります。
まとめ
JavaScriptのfilter
、map
、reduce
、some
、every
は非常に強力な関数で、配列操作を行う際にはこれらの関数を積極的に活用することをお勧めします。これらの関数を使うことで、コードが簡潔になり、読みやすくなるだけでなく、バグの発生を防ぐことも可能になります。また、複数の関数を組み合わせることで、より複雑な操作をシンプルに表現することができます。
これらの関数を理解し、使いこなすことで、より効率的で可読性の高いコードを書くことができるようになるでしょう。
以上、この記事はChatGPT-4が以下のプロンプトで書いたものを少し手直ししています。
JavaScriptでは、旧来はforループで書いていたものを、filter, map, reduce, some, every といった関数によって簡潔に、宣言的に書けるようになりました。
それについてMarkDown形式で記事を書いてください。記事はまず、filter, map, reduce, some, every の簡単な紹介を表形式でまとめ、各関数について、それらの関数を使わないforループによる「以前の書き方」を紹介し、それを各関数を用いた簡潔で宣言的なコードに置き換え、そうすることのメリットを提示してください。記事の最後には filter と mapを組み合わせた例も提示してください。サンプルコードでは数値の配列のようなシンプルなデータではなく、社員レコードのようなものを扱うようにしてください。