search
LoginSignup
1

More than 1 year has passed since last update.

posted at

updated at

JavaScript で if式っぽく動くようなswitch式...というかswitch関数作ったよ。

前の記事で if式 じゃなくて、if関数は作ってしまったのだ。

こちらの記事です。

JavaScriptの三項演算子が読みにくいらしいので、if式ならぬ if関数を作りました。そしてもっと読みにくい感。 - Qiita
https://qiita.com/standard-software/items/794724427fcee1cbd00b

どうせif関数も作ったので、真似て switch関数を作ります。

名前は「switch_」です。

値を渡したら、それを評価して分岐するという機能。

こんな書き方ができるようになります。


var switchValue = 1;
console.log(
  switch_(switchValue)([
    [1, 'Val1'], 
    [2, 'Val2'],
    [3, 'Val3'],
    ['1', 'ValStr1'],
    ['defaultVal']
  ])
);


var switchValue = '1';
console.log(
  switch_(switchValue)([
    [1, 'Val1'], 
    [2, 'Val2'],
    [3, 'Val3'],
    ['1', 'ValStr1'],
    'defaultVal'
  ])
);

特定条件によって値を代入するときに let 変数じゃなくて const 変数を使いたい場合でも、この「switch_関数」を使えば使い放題です。(使わなくても工夫したら使いたい放題だろうけれどもな)

上の書き方、細かくみてみるとわかるように、配列じゃない値を渡したり、長さ1の配列を渡すとそこがデフォルト値になります。

数値の1と、文字列の1の比較もできるぞ、という感じ。

なぜ配列にしているかというと、オブジェクトだと、{1: 'Val1', '1': 'ValStr1'} こんな書き方ができないから。オブジェクトのプロパティは全部文字列に変換されるらしいよ。

「switch_」関数の実装

ということで実装です。結構簡単。

const isFunction = (value) => {
  return (typeof value === 'function');
};

const functionValue = (value) => {
  if (isFunction(value)) {
    return value();
  } else {
    return value;
  }
};

const assert = function (value, message) {
  if (typeof message === 'undefined' || message === null) {
    message = '';
  }
  if (value !== true) {
    throw new Error(message);
  }
};

const switch_ = (expression) => {
  return (args) => {
    assert(Array.isArray(args), 'switch_ function');
    for (let i = 0; i < args.length; i += 1) {
      if (!Array.isArray(args[i])) {
        return args[i];
      } else if (args[i].length === 0) {
        return undefined;
      } else if (args[i].length === 1) {
        return args[i][0];
      } else {
        if (args[i][0] === expression) {
          return functionValue(args[i][1]);
        }
      }
    }
  };
};

if_関数の実装と同じように、内部で、functionValue を使っているので、次のように書けば、条件合致しない部分のものは、関数呼び出しそのものが行われません。

これで場合によっては、値によって関数呼び出しを制御する、ということも簡単にできます。

var switchValue = 2;
console.log(
  switch_(switchValue)([
    [1, _=>'Val1'], 
    [2, _=>'Val2'],
    [3, _=>'Val3'],
    ['1', _=>'ValStr1'],
    'defaultVal'
  ])
);

switch_関数は、if_関数よりかはいくらか実用的かもしれないですね。

まあ、これもお遊びみたいなものですが、こんなこともできる。ってことで。よろ。

追記

2019/03/21(木)

switch_ を組み込んだライブラリを npm で配信しています。TypeScriptコードです。

standard-software/copipejs: simple code parts
https://github.com/standard-software/copipejs

デフォルト値の記載方法を少し変えました。

https://github.com/standard-software/copipejs/blob/master/source/copipe_core.ts
このあたりのソースをみると実装がわかり、
https://github.com/standard-software/copipejs/blob/master/source/test/test_copipe_core.ts
こちらのテストコードをみると使い方がわかります。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
1