【问题标题】:Javascript: I am trying to use a switch statement to push strings to a new arrayJavascript:我正在尝试使用 switch 语句将字符串推送到新数组
【发布时间】:2017-02-21 05:37:02
【问题描述】:

挑战如下:编写一个函数,接收一个水果数组并返回一个可以在该数组中找到的颜色数组。相同颜色的水果将返回相同的值,但不会重复。

例如:

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

我正在尝试使用 switch 语句来解决这个问题,因为我想使用“fall-through”来处理所有语句。有人可以告诉我我做错了什么吗?

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

【问题讨论】:

    标签: javascript arrays switch-statement


    【解决方案1】:

    如果您需要一个比 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']);
    

    【讨论】:

    • 这让我觉得在精神上最接近 OP 要求的模式。
    • “如果您需要一个不太优雅的解决方案” - 这是一种有趣的表达方式。尽管我确实同意这更接近 OP 的想法。我可能会使用 switch 语句来设置一个临时变量currentColour = 'red',然后在 switch 之后执行.indexOf() 测试和.push() - 只是少一点重复。
    【解决方案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']));

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 不确定我是否会将其称为Array.reduce完美 用例。看起来您只是将.reduce 用作美化的.forEach
      • @JLRishe - 归根结底,.reduce()总是是正确答案。
      • @JLRishe: reduce 允许我们在单个语句中定义和设置输出变量(而不是let foundColors = []; fruitList.forEach((f) =&gt; { /*...*/ foundColors.push(f); })。类似于map 优于forEach。原因@此处使用 987654336@ 而不是 map 是因为,在这种情况下,输出数组不一定应该与输入数组的长度相同。
      【解决方案4】:

      不是您要找的那种——而且不像 Tom 的解决方案那样优雅,哇——但它确实使用了 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']);
      

      【讨论】:

        【解决方案5】:

        您似乎无缘无故地尝试使用switch 语句,而简单的if 语句就足够了。这将为您提供所需的“失败”流程,因为它只是一系列语句。

        另外,在.indexOf 中使用'oneValue' || 'anotherValue' 不会做你想做的事。 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']));

        【讨论】:

        • 不错。这正是 OP 试图实现的逻辑。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-23
        • 1970-01-01
        • 1970-01-01
        • 2021-02-17
        相关资源
        最近更新 更多