JavaScript 配列 Filter

JavaScript配列フィルター

JavaScriptの配列にはfilterというヘルパーが付いています。filterは、配列内で必要なエレメントだけを抽出することや重複したデータ消してリスト化することもできます。下記は数値[1,2,3,4,5]という配列内の2より大きい数値だけをフィルターしたコード例です。

console.log([1,2,3,4,5].filter(a1 => {
    return (a1 > 2)
}))

SafariJavaScriptコンソールで実行すると下のように表示されました。

Filterの実行結果 [3,4,5]
Filterの実行結果 [3,4,5]

この配列部分をそのままに文字列に置き換えても使えます。

console.log(["ガンダム","ガンキャノン","ガンタンク"].filter(a1 => {
    return (a1 >= "ガンタ")
}))
"ガンタ"でフィルターするとガンダムとガンタンクの2つが出てきた?
“ガンタ”でフィルターするとガンダムとガンタンクの2つが出てきた?

配列フィルターの1つ目の引数だけを使いましたが配列は3つの引数(value: string, index: number, array: string[])が使えます。これを使うと重複などの比較も可能です。

console.log(["ガンダム","ガンキャノン","ガンキャノン","ガンキャノン","ガンキャノン"].filter((a1, i1, _my) => {
    return _my.indexOf(a1) === i1
}))

ガンダム1個とガンキャノン4個入っていますが実行すると重複分のガンキャノンが1個になります。

JS 配列フィルターで文字列重複削除
JS 配列フィルターで文字列重複削除

その逆で 重複した4つのガンキャノンだけを取り出すには下のコードです。

console.log(["ガンダム","ガンキャノン","ガンキャノン","ガンキャノン","ガンキャノン"].filter((a1, i1, _my) => {
    return _my.indexOf(a1) !== _my.lastIndexOf(a1)
}))

重複で取り出したガンキャノン4つ_my.lastIndexOf(a1) !== i1を&&し1つに===で1個にもできます。

console.log(["ガンダム","ガンキャノン","ガンキャノン","ガンキャノン","ガンキャノン"].filter((a1, i1, _my) => {
    return _my.indexOf(a1) === i1 && _my.lastIndexOf(a1) !== i1
}))

実行すると[ガンキャノン]1個が表示されます。

配列がJSONなどの構造体の場合にもフィルターは使えます。下記コードはJSON配列を使ったフィルター例です。

console.log([{mobileSuit: "ガンダム", mainFlg: true},{mobileSuit: "ガンキャノン"}].filter(a1 => {
    return a1.mainFlg 
}))

mainFlgがtrueのエレメントをフィルターした配列を返しています。結果は下のようになりました。

配列の要素内mainFlgがtrueの場合だけをフィルター
配列の要素内mainFlgがtrueの場合だけをフィルター

JavaScript 配列をJSONに変換する

JavaScript Array To JSON

JavaScriptで不定長の配列変数の情報をJSON化するコードです。入力は、[“ドラゴン”, “ライガー”, “ポセイドン”]という配列を入れています。この配列は3つ固定ではなく何個セットしても大丈夫です。DynamoDBなどでExpressionAttributeValuesを設定する場合などに使えそうです。

const arrayToJSON = async(values) => {
    const columnName = ":ColumnName"
    let s = {}
    let i = 0
    values.forEach(aValue => {
        let element1 = columnName + String(++i)
        s[element1] = aValue
    })
    return {"ExpressionAttributeValues":s}
}
Promise.all([arrayToJSON(["ドラゴン", "ライガー", "ポセイドン"])]).then(prmsArr => {
    prmsArr.forEach(jValue => {
        console.log(JSON.stringify(jValue))
        //{"ExpressionAttributeValues":{":ColumnName1":"ドラゴン",":ColumnName2":"ライガー",":ColumnName3":"ポセイドン"}}
    })
})

AWS lambda zipファイルアップロード

AWSlambda zipアップロード

AWS lambdaはサーバーレスで関数処理を実行したい場合便利なサービスです。初めて試す場合シンプルにブラウザからコードを記述しテスト実行まで行えます。lambda関数をNode.js 12.xの設定で作成した場合初期のコードは下記のサンプル(index.js)が入っています。

exports.handler = async (event) => {
    // TODO implement
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};

index.jsに入る範囲でコードを書く分には、ブラウザの機能を使って書いてもいいとは思うのですが、複数のJSファイルで構成したい場合やnode_modulesを埋め込みたい場合ブラウザから手動で登録していくのは大変な作業です。このような場合lambdaには.zipファイルでのアップロードとS3からのファイルアップロードが利用できます。私の場合ローカル環境でテストしてzipファイルにまとめてlambdaへアップロードする方法を採用しています。ローカル環境でプログラムに必要なnode_modulesを先に入れてしまいます。そして、メイン実行するJSファイルをサンプルと同じくindex.jsという名前にしてexports.handlerに返す処理を埋め込みます。自分で作成したクラスモジュールなども別のJSファイルに入れます。その後下記コマンドでzipを実行します。

#プロジェクト内のディレクトリの場合
zip -r index.zip ./*

zipコマンドは-rオプションをつけるだけです。index.zipが完成したらブラウザ画面の[関数コード]のアクション内「.zip ファイルをアップロード」を選択します。

「.zip ファイルをアップロード」を選択
「.zip ファイルをアップロード」を選択

ファイルアップロードダイアログが表示されるのでアップロードさせるzipファイルを選択し[保存]ボタンを押します。アップロードが成功するとブラウザの関数コード編集が出来なくなるようです。

.zip ファイルをアップロードダイアログ
.zip ファイルをアップロードダイアログ