2017-02-21 20 views
3

これは難題です:フルーツ配列を取り、この配列で見つかる色の配列を返す関数を記述します。同じ色の果物は同じ値を返しますが、それ自体は繰り返されません。例えばJavascript:文字列を新しい配列にプッシュするswitch文を使用しようとしています

whatFruitColors(['apple', 'orange', 'mango']); 
// returns ['red', 'orange'] 

私はすべての文を処理するために、「フォールスルー」を使用したいと思いますので、私は、switch文でこれを解決しようとしています。誰かが私が間違っていることを教えてもらえますか?

var whatFruitColors = function(fruitArray){ 
    var fruitColors = []; 

    switch(fruitArray){ 
     case fruitArray.indexOf('pineapple' || 'banana') > -1): 
     fruitColors.push('yellow'); 

     case fruitArray.indexOf('mango' || 'orange') > -1): 
     fruitColors.push('orange'); 

     case fruitArray.indexOf('apple') > -1): 
     fruitColors.push('red'); 

     break; 
    } 

    console.log(fruitColors); 
    return fruitColors; 

} 

whatFruitColors(['pineapple','banana','apple','mango','orange']); 

答えて

3

あなたはArray.reduceよりもはるかに少ないエレガントな解決策が必要な場合は、次のようになります。

var whatFruitColors = function (fruitArray) { 
     var fruitColors = []; 

     for (var i = 0; i < fruitArray.length; i++) { 
      var item = fruitArray[i]; 
      switch (item) { 
       case 'pineapple': 
       case 'banana': 
        if (fruitColors.indexOf('yellow') === -1) { 
         fruitColors.push('yellow');  
        } 
        break; 
       case 'mango': 
       case 'orange': 
        if (fruitColors.indexOf('orange') === -1) { 
         fruitColors.push('orange'); 
        } 
        break; 
       case 'apple': 
        if (fruitColors.indexOf('red') === -1) { 
         fruitColors.push('red'); 
        } 
        break; 
      } 
     } 

     console.log(fruitColors); 

     return fruitColors; 
    }; 

    whatFruitColors(['pineapple', 'banana', 'apple', 'mango', 'orange']); 
+0

これは、OPの要求されたパターンに最も近い精神で私を襲います。 – Tom

+0

*「それほどエレガントではない解決策が必要な場合」* - それはそれを置く興味深い方法です。これは、OPが頭に浮かべていたと思われるものに近いです。私は一時的な変数 'currentColour = 'red''をセットし、' .indexOf() 'テストと' .push() 'スイッチの後にちょっとだけ繰り返す。 – nnnnnn

1

私はswitchがこれに適しているとは思わない。そして、私はあなたの "フォールスルー"パターンが失敗することが保証されていると思う:すべてのcaseステートメントは、トリガーされた後にもを実行します。

switchで作業することはできますが、「フォールスルー」を放棄する必要があります。個々の果物を繰り返し処理する必要があります。

あなただけの任意のループを回避したい場合は別の方法として、最も簡単な解決策はそうのように、非排他的if一連のステートメントを使用することです:

function whatFruitColors(fruitList) { 
    var results = []; 

    if(fruitList.indexOf('apple' ) >= 0 && results.indexOf('red' ) === -1) fruitList.push('red' ); 
    if(fruitList.indexOf('banana' ) >= 0 && results.indexOf('yellow') === -1) fruitList.push('yellow'); 
    if(fruitList.indexOf('kiwi' ) >= 0 && results.indexOf('green') === -1) fruitList.push('green'); 
    if(fruitList.indexOf('mango' ) >= 0 && results.indexOf('orange') === -1) fruitList.push('orange'); 
    if(fruitList.indexOf('orange' ) >= 0 && results.indexOf('orange') === -1) fruitList.push('orange'); 
    if(fruitList.indexOf('pineapple') >= 0 && results.indexOf('yellow') === -1) fruitList.push('yellow'); 

    return results; 
} 

whatFruitColors(['pineapple','banana','apple','mango','orange']); 

、これは動作しますが、それは率直に言って、粗です多くの還元剤コードがあります。また、これを維持する、すなわち新しい果物を追加する、果物と色の関連付けを維持することは、お尻に痛みを与えます。

ユークースケースArray.reduceです。ここではよりよい解決策は以下のとおりです。

function whatFruitColors(fruitList) { 
    // a static lookup "table" that declares the color of every fruit 
    var FRUIT_COLORS = { 
     'apple': 'red', 
     'banana': 'yellow', 
     'kiwi': 'green', 
     'mango': 'orange', 
     'orange': 'orange', 
     'pineapple': 'yellow' 
    }; 

    return fruitList.reduce(function(foundColors, thisFruit) { 
     var thisFruitColor = FRUIT_COLORS[thisFruit]; 
     if(foundColors.indexOf(thisFruitColor) === -1) { 
      foundColors.push(thisFruitColor); 
     } 

     return foundColors; 
    }, []); 
} 

whatFruitColors(['pineapple','banana','apple','mango','orange']); 
+0

ない私は 'Array.reduceため_perfect_ユースケースこれを呼びたいことを確認:あなたは.reduce()またはif文または任意の他の答えはなかった)一連のでこれを行うことができても'。栄光の '.forEach'として' .reduce'を使っているようです。 – JLRishe

+0

@JLRishe - それになると、 '.reduce()'は*常に*正しい答えです。 – nnnnnn

+0

@JLRishe: 'reduce'は、出力変数を(let foundColors = []; fruitList.forEach(f)=> {/*...*/ foundColors.pushの代わりに)単一のステートメントで定義して設定することを可能にします。 'map'が' forEach'よりどのように優れているかと同様です。ここでは 'map'の代わりに' reduce'が使われています。この場合、出力配列は必ず必要とされるわけではありません入力配列と同じ長さです – Tom

1

あなたが探しているではありませんかなり何 - トムさんのようにエレガントではありませんソリューション、うわー - それはswitchステートメントを使用します。 (私は、スイッチのケースでは条件文を置くことについて考えたが、それだけで終わりで結果をフィルタリングするためにすっきり見えた。)あなたは、ときがない本当の理由switchステートメントを使用しようとしているよう

var whatFruitColors = function(fruitArray){ 
    var fruitColors = []; 
    for (let fruit of fruitArray) { 
    switch(fruit){ 
     case 'pineapple': 
     case 'banana': 
     fruitColors.push('yellow'); 
      break; 
     case 'mango': 
     case 'orange': 
     fruitColors.push('orange'); 
      break; 
     case 'apple': 
     fruitColors.push('red'); 
      break; 
    } 
    } 
    let reducedFruits = fruitColors.filter((elem, index, self) => { 
     return index === self.indexOf(elem); 
    }); 
    console.log(reducedFruits); 
    return reducedFruits; 

} 

whatFruitColors(['pineapple','banana','apple','mango','orange']); 
1

らしいです単純なifステートメントで十分です。これは単なる一連のステートメントなので、必要な「フォールスルー」フローを提供します。

'oneValue' || 'anotherValue'.indexOfの中にも、あなたがしようとしていることはありません。 fruitArray.indexOf('pineapple' || 'banana')は、機能的にはfruitArray.indexOf('pineapple')と同一です。 'banana'部分は無視されます。

var whatFruitColors = function(fruitArray) { 
 
    var fruitColors = []; 
 

 
    if (fruitArray.indexOf('pineapple') > -1 || 
 
     fruitArray.indexOf('banana') > -1) { 
 
    fruitColors.push('yellow'); 
 
    } 
 

 
    if (fruitArray.indexOf('mango') > -1 || 
 
     fruitArray.indexOf('orange') > -1) { 
 
    fruitColors.push('orange'); 
 
    } 
 

 
    if (fruitArray.indexOf('apple') > -1) { 
 
    fruitColors.push('red'); 
 
    } 
 

 
    console.log(fruitColors); 
 
    return fruitColors; 
 
} 
 

 
whatFruitColors(['pineapple', 'banana', 'apple', 'mango', 'orange']);

あなたはまた、 .filter .someを使用し、よりクリーンで拡張可能な実装を使用することができ

、および.map:その他WHE説明した

function whatFruitColors(fruits) { 
 
    var fruitColors = [{ 
 
     color: 'red', 
 
     fruits: ['apple'] 
 
    }, 
 
    { 
 
     color: 'yellow', 
 
     fruits: ['banana', 'pineapple'] 
 
    }, 
 
    { 
 
     color: 'orange', 
 
     fruits: ['mango', 'orange'] 
 
    } 
 
    ]; 
 

 
    return fruitColors.filter(function(item) { 
 
     return item.fruits.some(function(fruit) { 
 
     return fruits.indexOf(fruit) > -1; 
 
     }); 
 
    }) 
 
    .map(function(item) { 
 
     return item.color; 
 
    }); 
 
} 
 

 
console.log(whatFruitColors(['banana', 'mango', 'orange']));

+0

ニースこれはまさにOPが実装しようとしたロジックです。 – nnnnnn

2

あなたは間違っていましたが、重複がない配列を作成しようとしているときに、プレーンなオブジェクトを作業変数として使用し、そのオブジェクトからキーを取るほうが簡単な場合があることを示す答えを追加すると思いました最後に、特定の項目がすでに存在するかどうかのテストを行う必要がありません。

あなたがしている場合:

var fruits = {}; 

...そしてあなたが言うことができます。

fruits['yellow'] = true; 

を...など、多くの好きなように時間とfruitsオブジェクトは、まだ名前のプロパティを1つだけ持っていますyellow。 (プロパティが他の値よりも論理的に見えるので、trueを提案します)

文脈で(まだswitchステートメントを使用していますが、

var whatFruitColors = function(fruitArray){ 
 
    var fruitColors = {}; 
 

 
    fruitArray.forEach(function(fruit) { 
 
    switch(fruit){ 
 
     case 'pineapple': 
 
     case 'banana': 
 
     fruitColors['yellow'] = true; 
 
     break; 
 

 
     case 'mango': 
 
     case 'orange': 
 
     fruitColors['orange'] = true; 
 
     break; 
 

 
     case 'apple': 
 
     fruitColors['red'] = true; 
 
     break; 
 
    } 
 
    }); 
 
    console.log(fruitColors); 
 
    return Object.keys(fruitColors); 
 
} 
 

 
console.log(whatFruitColors(['pineapple','banana','apple','mango','orange']));

関連する問題