情報アイランド

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

Node.jsで配列を非同期的にフィルタする

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

  • async.filter関数
  • async.filterLimit関数
  • async.filterSeries関数
  • async.reject関数
  • async.rejectLimit関数
  • async.rejectSeries関数

フィルタ条件を満たさない要素を配列から除外したい場合にはasync.filter関数、async.filterLimit関数、async.filterSeries関数の何れかを使用し、フィルタ条件を満たす要素を除外したい場合にはasync.reject関数、async.rejectLimit関数、async.rejectSeries関数の何れかを使用します。

また、フィルタ処理を完全に並列的に実行したい場合にはasync.filter関数かasync.reject関数を使用し、並列的に実行するフィルタ処理の最大数を指定して実行したい場合にはasync.filterLimit関数かasync.rejectLimit関数を使用し、直列的に実行したい場合にはasync.filterSeries関数かasync.rejectSeries関数を使用します。

なお、フィルタ処理の実行中にエラーが発生しても既に開始している他の要素に対するフィルタ処理の実行は続行しますので注意してください。しかし、まだ開始していない要素に対するフィルタ処理の実行は行われません。

また、配列の要素の順序は保持されます。

async.filter関数とasync.filterSeries関数とasync.reject関数とasync.rejectSeries関数

var async = require('async');

async.filter(['xxx', 'yyy', 'zzz'], function (item, callback) {
    callback(null, true);
    //or
    callback(null, false);
    //or
    callback(new Error('aaa'), null);
}, function (err, array) {
});
async.filterSeries(['xxx', 'yyy', 'zzz'], function (item, callback) {
    callback(null, true);
    //or
    callback(null, false);
    //or
    callback(new Error('aaa'), null);
}, function (err, array) {
});
async.reject(['xxx', 'yyy', 'zzz'], function (item, callback) {
    callback(null, true);
    //or
    callback(null, false);
    //or
    callback(new Error('aaa'), null);
}, function (err, array) {
});
async.rejectSeries(['xxx', 'yyy', 'zzz'], function (item, callback) {
    callback(null, true);
    //or
    callback(null, false);
    //or
    callback(new Error('aaa'), null);
}, function (err, array) {
});

第1引数

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

第2引数

第2引数にフィルタ条件を関数として指定します。

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

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

このコールバック関数の第1引数にはエラーオブジェクト(エラーが発生しなかった場合にはnull)を指定し、第2引数には配列の要素がフィルタ条件を満たすかどうかを真偽値として指定します(エラーが発生した場合にはnullを指定します)。

第3引数

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

この関数の第1引数はエラーオブジェクトであり、第2引数はフィルタ後の配列です。

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

async.filterLimit関数とasync.rejectLimit関数

async.filterLimit(['xxx', 'yyy', 'zzz'], 10, function (item, callback) {
    callback(null, true);
    //or
    callback(null, false);
    //or
    callback(new Error('aaa'), null);
}, function (err, array) {
});
async.rejectLimit(['xxx', 'yyy', 'zzz'], 10, function (item, callback) {
    callback(null, true);
    //or
    callback(null, false);
    //or
    callback(new Error('aaa'), null);
}, function (err, array) {
});

async.filter関数やasync.filterSeries関数やasync.reject関数やasync.rejectSeries関数とほぼ同じですが、第1引数と第2引数の間に並列的に実行するフィルタ処理の最大数を指定します。

サンプルコード1

async-filter.js

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

var xs = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
async.filterSeries(xs, function (item, callback) {
    setTimeout(function () {
        util.log(item);
        callback(null, item % 2 === 1);
    }, Math.random() * 1000);
}, function (err, results) {
    if (err) {
        console.error(err);
        process.exit(1);
    }
    else {
        console.log(results);
        async.filter(xs, function (item, callback) {
            setTimeout(function () {
                util.log(item);
                callback(null, item % 2 === 1);
            }, Math.random() * 1000);
        }, function (err, results) {
            if (err) {
                console.error(err);
                process.exit(1);
            }
            else {
                console.log(results);
                async.filterLimit(xs, 2, function (item, callback) {
                    setTimeout(function () {
                        util.log(item);
                        callback(null, item % 2 === 1);
                    }, Math.random() * 1000);
                }, function (err, results) {
                    if (err) {
                        console.error(err);
                        process.exit(1);
                    }
                    else {
                        console.log(results);
                    }
                });
            }
        });
    }
});

使用パッケージ

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

実行結果

C:\work\node>node async-filter.js
3 Jun 11:36:18 - 0
3 Jun 11:36:18 - 1
3 Jun 11:36:19 - 2
3 Jun 11:36:19 - 3
3 Jun 11:36:20 - 4
3 Jun 11:36:20 - 5
3 Jun 11:36:21 - 6
3 Jun 11:36:21 - 7
3 Jun 11:36:21 - 8
3 Jun 11:36:22 - 9
[ 1, 3, 5, 7, 9 ]
3 Jun 11:36:22 - 5
3 Jun 11:36:22 - 3
3 Jun 11:36:22 - 2
3 Jun 11:36:22 - 7
3 Jun 11:36:22 - 4
3 Jun 11:36:22 - 0
3 Jun 11:36:22 - 6
3 Jun 11:36:22 - 8
3 Jun 11:36:22 - 9
3 Jun 11:36:23 - 1
[ 1, 3, 5, 7, 9 ]
3 Jun 11:36:23 - 0
3 Jun 11:36:23 - 1
3 Jun 11:36:24 - 2
3 Jun 11:36:24 - 3
3 Jun 11:36:24 - 4
3 Jun 11:36:25 - 6
3 Jun 11:36:25 - 5
3 Jun 11:36:25 - 8
3 Jun 11:36:25 - 7
3 Jun 11:36:26 - 9
[ 1, 3, 5, 7, 9 ]

関連

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

-Node.js