プログラミングBlog

アプリ開発サークル勉強会⑤ 開催日時 2021年1月30日(土) 7:00-9:00

JavaScript問題集

本日は1月最後の勉強会となりました。
サークルの皆様のおかげで無事1ヵ月勉強会を開催し続けることができて嬉しく思います!
今後は活動の幅を広げつつ続けていきたいと思います。
では問題集の続きをやっていきましょう。
Q21-25 https://gist.github.com/kenmori/1961ce0140dc3307a0e641c8dde6701d

Sort()について

配列に格納した値を昇順、降順に並べ替えて結果を表示したいときってありますよね??
JavaScriptにもSort()という並べ替えてくれる便利な関数があるので使ってみました。
developer.mozilla.org

ただし、癖があるので注意しないといけないようです。

要素を文字列に変換してから、UTF-16 コード単位の値の並びとして比較します。


どういうことかというと、

const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);

これらの配列をソートした結果がこうなります。

> Array [1, 100000, 21, 30, 4]

ほんとうにソートされてるの??って最初は疑問に思いましたが、ドキュメントを読んで理解できましたが、UTF-16の並びだとこうなるようです。 仕様通りですね。
ただこのままだと癖が強すぎて使えないため、引数にcompareFunctionこちらの関数を使って比較してあげると昇順と降順が可能となります。
やっていきましょう。

数値のソート

array1.sort(function (a, b) {
    return a - b;
});
console.log(array1);

結果こうなります。

[ 1, 4, 21, 30, 100000 ]

想定通りですね! 今回は昇順でソートしましたが、降順でソートしたい場合はa - b → b - a 値を入れ替えれば問題なく降順にできました。
次は文字の比較をしてみます。文字の比較の場合はこう書きます。

文字列のソート

array2 = ['e', 'a', 'd', 'b', 'c'];

array2.sort(function (a, b) {
    if (a < b) {
        return -1;
    }
    if (a > b) {
        return 1;
    }
    return 0;
});

console.log(array2);

結果

[ 'a', 'b', 'c', 'd', 'e' ]

a,bの値を比較して返却されてくる結果が負か正でどちらが大きいかの判別をするみたいですね。
こちらも数値の時と考え方は同じで不等号を反対にすると降順にできます。 sort使わずに自分で書くと結構大変なのでどんどん使っていきましょう。

カリー化 と部分適用について

部分適用とは 複数の引数をとる関数の一部の引数に実引数を適用する操作のこと


カリー化とは ja.wikipedia.org

複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること(あるいはその関数のこと)である。

最初の引数だけに 1 を適用すれば、インクリメント用の関数が簡単に作れる。  

ユースケースとしては何かしらの同じような処理があるときに使えそうですね。
WikiPediaに載っていたこの仕様を実装してみましょう。

addStock

在庫数を引数の数だけインクリメントする関数
カリー化なしで書くとこんな感じになります。

const productName = {
    orange: 0,
    apple: 0,
    banana: 0
}

function addStock(num, name) {
    return console.log(Math.floor(productName[name] += num));
}

addStock(1, "orange");

addStockAll

在庫数を引数の数だけインクリメントする関数
こちらはカリー化した場合。
引数numに在庫数、引数nameに名前が入ります。
引数が最初の引数で、残りの引数をaddStockCurryで定義した関数内で取り、結果を返す。
引数を一つだけにしてaddStockに渡しています。

function addStockCurry(num) {
    return function (name) { return console.log(productName[name] += num) };
}

addStockCurry(1)("orange");

部分適用
引数1の値が固定化されて、在庫に加算されます

var addStockCurry1 = addStockCurry(1);
addStockCurry1("orange");

こちらは最初の引数に渡した値を全ての在庫に対してインクリメントした結果を返す関数。
引数に渡した1の値が部分適合にあたります。

Object.keys(productName).forEach(addStockCurry(1));

カリー化と部分適合による数値の固定化でスッキリしたコードが書くことができました。

カリー化参考サイト

kenju.gitbooks.io qiita.com