Help us understand the problem. What is going on with this article?

for文を使わないでやってみた

はじめに

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! JapanGoogle へリクエスト送信を並列処理で行います。

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文へ書き直してみてください。

walk8243
ただの乃木オタです。 業務中に感じた良く分からない気持ち悪さを、形にして解決するにはどうしたらいいかを考えながら記事を書いてます。 執筆は握手会の会場でできるからいいですね!
yahoo-japan-corp
Yahoo! JAPAN を運営しています。
https://www.yahoo.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした