はじめに
for文は色々な言語で用意されており、様々なところで使われています。
実際、同じ処理を複数回するときに便利です。
また、for文が使われていれば、容易に繰り返し同じことをしていると分かります。
簡単であり、可読性が高いという点で、for文は優れていると思います。
しかし、それは処理という面で捉えるからです。
オブジェクトという面で見たときは、拡張for文の登場によって扱えるとは言え、優れているとは言えないでしょう。
JavaScriptにはちゃんと Array というビルドインオブジェクトが用意されているので、それを使って繰り返す処理を書くことも選択肢に入れましょう。
という訳で、今回はfor文からArrayを使った書き方に移行する方法を紹介していきたいと思います。
指定回数繰り返す
10回ログに出力します。
// for文
for(let i=0; i<10; i++) {
console.log('repeat:', i);
}
// Array
[...Array(10)].forEach((_, i) => {
console.log('repeat:', i);
});
[...Array(10)]
のようにすることで、固定長の配列を作成することができます。
ここで使っているのは、 Array.prototype.forEach() です。
与えられた配列の中身を順番に実行して、新しく配列を生成する必要の無い場合は、これを使うことができます。
指定範囲の配列を作成する
1から10までの2つおきの配列を作成します。
// for文
const vFor = [];
for(let i=1; i<=10; i+=2) {
vFor.push(i);
}
console.log(vFor); // [ 1, 3, 5, 7, 9 ]
// Array
const range = (start: number, stop: number, step: number) => {
return Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
}
const vArray = range(1, 10, 2);
console.log(vArray); // [ 1, 3, 5, 7, 9 ]
ここで使っているのは、 Array.from() です。
新しく配列を生成したいときに使うことができます。
配列の値それぞれを加工する
5人の国語・数学・英語・理科・社会の5教科の合計得点を計算します。
const scores = [
{ '国語': 85, '数学': 78, '英語': 92, '理科': 62, '社会': 69 },
{ '国語': 23, '数学': 44, '英語': 78, '理科': 44, '社会': 50 },
{ '国語': 86, '数学': 10, '英語': 56, '理科': 82, '社会': 90 },
{ '国語': 31, '数学': 42, '英語': 96, '理科': 49, '社会': 68 },
{ '国語': 70, '数学': 55, '英語': 48, '理科': 89, '社会': 11 },
];
// for文
const vFor = [];
for(const score of scores) {
vFor.push(score.国語 + score.数学 + score.英語 + score.理科 + score.社会);
}
console.log(vFor); // [ 386, 239, 324, 286, 273 ]
// Array
const vArray = scores.map((score) => {
return score.国語 + score.数学 + score.英語 + score.理科 + score.社会;
});
console.log(vArray); // [ 386, 239, 324, 286, 273 ]
ここで使っているのは、 Array.prototype.map() です。
Array.prototype.forEach
と異なり、与えられた配列の中身を順番に実行して、新しく配列を作成したい場合に、これを使うことができます。
配列の値をまたがって加工して1つの値を作成する
教科ごとの合計得点を計算します。
const scores = [
{ '国語': 85, '数学': 78, '英語': 92, '理科': 62, '社会': 69 },
{ '国語': 23, '数学': 44, '英語': 78, '理科': 44, '社会': 50 },
{ '国語': 86, '数学': 10, '英語': 56, '理科': 82, '社会': 90 },
{ '国語': 31, '数学': 42, '英語': 96, '理科': 49, '社会': 68 },
{ '国語': 70, '数学': 55, '英語': 48, '理科': 89, '社会': 11 },
];
// for文
const vFor = { '国語': 0, '数学': 0, '英語': 0, '理科': 0, '社会': 0 };
for(const score of scores) {
vFor.国語 += score.国語;
vFor.数学 += score.数学;
vFor.英語 += score.英語;
vFor.理科 += score.理科;
vFor.社会 += score.社会;
}
console.log(vFor); // { '国語': 295, '数学': 229, '英語': 370, '理科': 326, '社会': 288 }
// Array
const vArray = scores.reduce((previous, score) => {
return {
'国語': previous.国語 + score.国語,
'数学': previous.数学 + score.数学,
'英語': previous.英語 + score.英語,
'理科': previous.理科 + score.理科,
'社会': previous.社会 + score.社会,
};
}, { '国語': 0, '数学': 0, '英語': 0, '理科': 0, '社会': 0 });
console.log(vArray); // { '国語': 295, '数学': 229, '英語': 370, '理科': 326, '社会': 288 }
ここで使っているのは、 [Array.prototype.reduce()] です。(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) です。
与えられた配列の中身を順番に実行して、1つの値を作成したい場合に、これを使うことができます。
データを基に並列処理を行う
Yahoo! Japan と Google へリクエスト送信を並列処理で行います。
import fetch from 'node-fetch';
const urls = [
'https://www.yahoo.co.jp/',
'https://www.google.com/',
];
// for文
(async () => {
const promises = [];
for(const url of urls) {
promises.push((async () => {
const response = await fetch(url);
return await response.text();
})());
}
console.log(await Promise.all(promises));
})();
// Array
(async () => {
console.log(
await Promise.all(
urls.map(async (url) => {
const response = await fetch(url);
return await response.text();
})
)
);
})();
リクエストの送信には、 node-fetchを使用しています。
Array側の方が階層は深くなってしまっていますが、書いている内容はシンプルです。
内容としては、 Array.prototype.map() を使って、 Promise
が返る配列を作成し、それを Promise.all
に渡しています。
(番外編)for...in
教科の一覧を表示します。
const score = { '国語': 86, '数学': 10, '英語': 56, '理科': 82, '社会': 90 };
// for文
for(const key in score) {
console.log(key);
}
// Array
Object.keys(score).forEach((key) => {
console.log(key);
});
for...in
の書き換えには、 Object.keys() を併用します。
keyの一覧を配列として取得してからは、 Array.prototype.forEach()
でも Array.prototype.map()
でも Array.prototype.reduce()
でも使用することができます。
おわりに
for文とArrayを使った書き方は、どちらがお好みでしょうか?
試しに作っているコードを、for文からArrayへ、Arrayからfor文へ書き直してみてください。