情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

Node.jsで配列を非同期的に集計する

配列を非同期的に集計するにはasyncモジュールの下のような関数を使用します。

  • async.reduce関数
  • async.reduceRight関数

配列の最初の要素から順番に集計を行うにはasync.reduce関数を使用し、最後の要素から順番に集計を行うにはasync.reduceRight関数を使用します。

なお、集計処理の実行中にエラーが発生した場合にはそれ以降の集計処理の実行は行われません。

async.reduce関数とasync.reduceRight関数

var async = require('async');

async.reduce(['xxx', 'yyy', 'zzz'], 'aaa', function (acc, item, callback) {
    callback(null, 'bbb');
    //or
    callback(new Error('ccc'), null);
}, function (err, acc) {
});
async.reduceRight(['xxx', 'yyy', 'zzz'], 'aaa', function (acc, item, callback) {
    callback(null, 'bbb');
    //or
    callback(new Error('ccc'), null);
}, function (err, acc) {
});

第1引数

第1引数に配列を指定します。あるいは、配列以外のイテラブルを指定することもできます。

第2引数

第2引数に集計値の初期値を指定します。

第3引数

第3引数に現在の集計値と配列の要素の値から新しい集計値を計算する処理を関数として指定します。

この関数の第1引数は現在の集計値であり、第2引数は配列の要素の値であり、第3引数はコールバック関数です。

集計処理が完了した場合や集計処理の実行中にエラーが発生した場合には必ずこのコールバック関数を呼び出さなければなりません。

このコールバック関数の第1引数にはエラーオブジェクト(エラーが発生しなかった場合にはnull)を指定し、第2引数には新しい集計値を指定します(エラーが発生した場合にはnullを指定します)。

第4引数

第4引数に配列の集計が完了したか、集計処理の実行中にエラーが発生した場合に呼び出されるコールバック関数を指定します。

この関数の第1引数はエラーオブジェクトであり、第2引数は集計値です。

この引数は指定しなくても構いません。

サンプルコード1

async.reduce関数とasync.reduceRight関数の何れを使っても集計値が変わらない例です。

async-reduce-same.js

var async = require('async');
var util = require('util');

var xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
async.reduce(xs, 0, function (red, item, callback) {
    setTimeout(function () {
        util.log(item);
        console.log(red + ' + ' + item + ' = ' + (red + item));
        callback(null, red + item);
    }, Math.random() * 1000);
}, function (err, result) {
    if (err) {
        console.error(err);
        process.exit(1);
    }
    else {
        console.log(result);
        async.reduceRight(xs, 0, function (red, item, callback) {
            setTimeout(function () {
                util.log(item);
                console.log(red + ' + ' + item + ' = ' + (red + item));
                callback(null, red + item);
            }, Math.random() * 1000);
        }, function (err, result) {
            if (err) {
                console.error(err);
                process.exit(1);
            }
            else {
                console.log(result);
            }
        });
    }
});

使用パッケージ

  • Async.js
    npm install asyncでインストールします。

実行結果

C:\work\node>node async-reduce-same.js
4 Jun 11:40:29 - 0
0 + 0 = 0
4 Jun 11:40:29 - 1
0 + 1 = 1
4 Jun 11:40:30 - 2
1 + 2 = 3
4 Jun 11:40:30 - 3
3 + 3 = 6
4 Jun 11:40:31 - 4
6 + 4 = 10
4 Jun 11:40:32 - 5
10 + 5 = 15
4 Jun 11:40:32 - 6
15 + 6 = 21
4 Jun 11:40:33 - 7
21 + 7 = 28
4 Jun 11:40:33 - 8
28 + 8 = 36
4 Jun 11:40:34 - 9
36 + 9 = 45
45
4 Jun 11:40:35 - 9
0 + 9 = 9
4 Jun 11:40:36 - 8
9 + 8 = 17
4 Jun 11:40:36 - 7
17 + 7 = 24
4 Jun 11:40:36 - 6
24 + 6 = 30
4 Jun 11:40:37 - 5
30 + 5 = 35
4 Jun 11:40:37 - 4
35 + 4 = 39
4 Jun 11:40:38 - 3
39 + 3 = 42
4 Jun 11:40:39 - 2
42 + 2 = 44
4 Jun 11:40:39 - 1
44 + 1 = 45
4 Jun 11:40:39 - 0
45 + 0 = 45
45

サンプルコード2

async.reduce関数とasync.reduceRight関数の何れを使うかで集計値が変わる例です。

async-reduce-not-same.js

var async = require('async');
var util = require('util');

var xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
async.reduce(xs, 0, function (red, item, callback) {
    setTimeout(function () {
        util.log(item);
        console.log(item + ' - ' + red + ' = ' + (item - red));
        callback(null, item - red);
    }, Math.random() * 1000);
}, function (err, result) {
    if (err) {
        console.error(err);
        process.exit(1);
    }
    else {
        console.log(result);
        async.reduceRight(xs, 0, function (red, item, callback) {
            setTimeout(function () {
                util.log(item);
                console.log(item + ' - ' + red + ' = ' + (item - red));
                callback(null, item - red);
            }, Math.random() * 1000);
        }, function (err, result) {
            if (err) {
                console.error(err);
                process.exit(1);
            }
            else {
                console.log(result);
            }
        });
    }
});

使用パッケージ

  • Async.js
    npm install asyncでインストールします。

実行結果

C:\work\node>node async-reduce-not-same.js
4 Jun 11:44:35 - 0
0 - 0 = 0
4 Jun 11:44:36 - 1
1 - 0 = 1
4 Jun 11:44:36 - 2
2 - 1 = 1
4 Jun 11:44:37 - 3
3 - 1 = 2
4 Jun 11:44:38 - 4
4 - 2 = 2
4 Jun 11:44:38 - 5
5 - 2 = 3
4 Jun 11:44:39 - 6
6 - 3 = 3
4 Jun 11:44:40 - 7
7 - 3 = 4
4 Jun 11:44:41 - 8
8 - 4 = 4
4 Jun 11:44:41 - 9
9 - 4 = 5
5
4 Jun 11:44:42 - 9
9 - 0 = 9
4 Jun 11:44:43 - 8
8 - 9 = -1
4 Jun 11:44:44 - 7
7 - -1 = 8
4 Jun 11:44:45 - 6
6 - 8 = -2
4 Jun 11:44:45 - 5
5 - -2 = 7
4 Jun 11:44:45 - 4
4 - 7 = -3
4 Jun 11:44:46 - 3
3 - -3 = 6
4 Jun 11:44:47 - 2
2 - 6 = -4
4 Jun 11:44:47 - 1
1 - -4 = 5
4 Jun 11:44:48 - 0
0 - 5 = -5
-5

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-Node.js