コーディングのヒント:Ifステートメントなしでコーディングを試みる

より良い解決策を見つけるかもしれません

Facebookプロジェクトのコード。訴えないでください。
更新:この記事は、私の本「最新のJavaScriptによるコーディングの学習」の一部になりました。
jscomplete.com/no-ifsで更新バージョンを読んでください。

プログラミングの初心者にコードチャレンジを教えるとき、私のお気に入りのフォローアップチャレンジの1つは、if文(または三項演算子、switch文)を使用せずに同じ問題を解決することです。

なぜそれが役立つのかと尋ねるかもしれません。

まあ、私はこの挑戦があなたの脳に異なる考え方を強制し、場合によっては異なる解決策がより良いかもしれないと思う。

if文を使用しても問題はありませんが、それらを回避すると、コードが人間にとって読みやすくなる場合があります。これは間違いなく一般的なルールではありません。if文を避けるとコードが読みにくくなることがあります。あなたが裁判官です。

if文を避けることは読みやすさだけではありません。この概念の背後にはいくつかの科学があります。以下の課題が示すように、ifステートメントを使用しないことで、コードとしてのデータの概念に近づくことができます。これにより、実行中のコードを変更するなどの独自の機能が可能になります。

すべての場合において、条件を使用せずにコーディングの課題を試して解決することは常に楽しいです。

ifベースのソリューションとif-lessソリューションの課題の例を次に示します。すべてのソリューションはJavaScriptで記述されています。

どのソリューションがより読みやすいと思いますか教えてください。

課題1:配列内の奇数の整数を数える

整数の配列があり、これらの整数の数が奇数であるとカウントしたいとしましょう。

以下にテストする例を示します。

const arrayOfIntegers = [1、4、5、9、0、-1、5];

ifステートメントを使用したソリューションは次のとおりです。

let counter = 0;
arrayOfIntegers.forEach((integer)=> {
  const残り= Math.abs(integer%2);
  if(remainder === 1){
    counter ++;
  }
});
console.log(counter);

ifステートメントを使用しないソリューションを次に示します。

let counter = 0;
arrayOfIntegers.forEach((integer)=> {
  const残り= Math.abs(integer%2);
  カウンター+ =余り;
});
console.log(counter);

注:上記の例ではforEachを使用し、カウンター変数を変更しています。代わりに不変のメソッドを使用する方がクリーンで安全です。ただし、この記事はそのトピックに関するものではありません。不変性と関数型プログラミングをカバーするコーディングのヒントに関する記事をお楽しみに。また、David Nagliが指摘したように、if-lessソリューションは整数に対してのみ機能しますが、ifベースのソリューションには10進数を含む任意の数を処理できるという利点があります。

if-lessソリューションでは、モジュラス2演算の結果が常に1(奇数の場合)または0(偶数の場合)であるという事実を利用しています。この結果はデー​​タです。そのデータを直接使用しました。

偶数の整数を数えるのはどうですか? ifステートメントを使用せずにそれを行う方法を考えることができますか?

課題#2:weekendOrWeekday関数

日付オブジェクト引数(new Date()など)を取り、文字列「weekend」または「weekday」を返す関数を作成します。

ifステートメントを使用したソリューションは次のとおりです。

const weekendOrWeekday =(inputDate)=> {
  const day = inputDate.getDay();
  if(day === 0 || day === 6){
    「週末」を返します。
  }
  
  「平日」を返す;
  //または、三者ファンの場合:
  // return(day === 0 || day === 6)? 'weekend': 'weekday';
};
console.log(weekendOrWeekday(new Date()));

ifステートメントを使用しないソリューションを次に示します。

const weekendOrWeekday =(inputDate)=> {
  const day = inputDate.getDay();
  return weekendOrWeekday.labels [day] ||
         weekendOrWeekday.labels ['default'];
};
weekendOrWeekday.labels = {
  0:「週末」、
  6:「週末」、
  デフォルト: 'weekday'
};
console.log(weekendOrWeekday(new Date()));

if文の条件にデータが含まれていることに気付きましたか?どの日が週末かがわかります。 ifステートメントを回避するために行ったのは、そのデータをオブジェクトに抽出し、そのオブジェクトを直接使用することです。また、そのデータをより高い汎用レベルで保存することもできます。

更新:Harald Niescheは、||上記のトリックは技術的に条件付きのものです。 「平日」を5回繰り返さないように使用することを選択しました。 7日間全体をlabelsオブジェクトに入れれば、簡単に削除できます。

課題#3:ダブラー機能(ここではドラゴン)

入力のタイプに基づいて、以下を実行するダブラー関数を作成します。

  • 入力が数値の場合、それは2倍になります(つまり、5 => 10、-10 => -20)。
  • 入力が文字列の場合、すべての文字が繰り返されます(つまり、「hello」=>「hheelloo」)。
  • 入力が関数の場合、2回呼び出します。
  • 入力が配列の場合、その配列のすべての要素でそれ自体を呼び出します。
  • 入力がオブジェクトの場合、そのオブジェクトのすべての値で自身を呼び出します。

スイッチステートメントを使用したソリューションは次のとおりです。

const doubler =(入力)=> {
  スイッチ(入力のタイプ){
    ケース「番号」:
      入力+入力を返します。
    ケース 'string':
      入力を返す
        。スプリット('')
        .map((letter)=> letter + letter)
        .join( '');
    ケース「オブジェクト」:
      Object.keys(入力)
            .map((key)=>(input [key] = doubler(input [key])));
      入力を返す;
    ケース「機能」:
      入力();
      入力();
  }
};
console.log(doubler(-10));
console.log(doubler( 'hey'));
console.log(doubler([5、 'hello']));
console.log(doubler({a:5、b: 'hello'}));
console.log(
  doubler(function(){
    console.log( 'call-me');
  })、
);

スイッチステートメントのないソリューションを次に示します。

const doubler =(入力)=> {
  return doubler.operationsByType [typeof input](input);
};
doubler.operationsByType = {
  数値:(入力)=>入力+入力、
  文字列:(入力)=>
    入力
      。スプリット('')
      .map((letter)=> letter + letter)
      .join( '')、
  関数:(入力)=> {
    入力();
    入力();
  }、
  オブジェクト:(入力)=> {
    Object.keys(入力)
          .map((key)=>(input [key] = doubler(input [key])));
    入力を返す;
  }、
};
console.log(doubler(-10));
console.log(doubler( 'hey'));
console.log(doubler([5、 'hello']));
console.log(doubler({a:5、b: 'hello'}));
console.log(
  doubler(function(){
    console.log( 'call-me');
  })、
);

繰り返しますが、データ(どの操作がどの入力タイプに対して行われるべきか)がすべてswitchステートメントからオブジェクトに抽出される方法に注目してください。次に、オブジェクトを使用して正しい操作を選択し、元の入力で呼び出します。

いくつかの例を見てきましたが、あなたの考えは何ですか?これらの2つのコーディングスタイルのいずれかに賛成または反対する議論はありますか?

読んでくれてありがとう。