2017-02-21 73 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的想法,也许可以使用switch语句设置一个临时变量'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']); 

这是可行的,但它是坦言原油,还有很多redudant代码。此外,保持这一点 - 即增加新的水果,保持水果+颜色组合的名单 - 将是一个痛苦的屁股。

这是一个完美用例为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

不知道我会打电话给这个_perfect_用例为'Array.reduce '。看起来你只是使用'.reduce'作为荣耀的'.forEach'。 – JLRishe

+0

@JLRishe - 当它归结时,'.reduce()'总是*正确的答案。 – nnnnnn

+0

@JLRishe:'reduce'允许我们在一个语句中定义和设置输出变量(而不是'let foundColors = []; fruitList.forEach((f)=> {/*...*/ foundColors.push (f);})'类似于'map'比'forEach'更好的原因'reduce'在这里被使用来代替'map',因为在这种情况下,输出数组并不是必须被假定为长度与输入阵列相同 – Tom

1

不太你要找的 - 而不是优雅的汤姆解决方案,哇 - 但它确实使用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

好像你正在尝试使用一个switch声明没有真正的理由,当简单的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

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对象将仍然只有一个属性命名yellow。 (该值分配给该属性可以是任何东西,因为点就是创造财产,但我建议true,因为它似乎比其他可能的值更符合逻辑。)

在上下文(依然采用了switch声明,虽然你可以做到这一点与.reduce()或一系列if陈述或任何其他的答案一样):

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']));