2017-02-21 23 views
3

Вот вызов: Напишите функцию, которая принимает массив фруктов и возвращает массив цветов, который можно найти в этом массиве. Плоды того же цвета возвращают одинаковое значение, но не повторяются.Javascript: Я пытаюсь использовать оператор switch для перевода строк в новый массив.

Например:

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

Я пытаюсь решить эту проблему с помощью переключателя заявление, потому что я хотел бы использовать «осень-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']); 

ответ

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

* «Если вам нужно гораздо менее элегантное решение» * - Это интересный способ выразить это. Хотя я согласен с тем, что это ближе к тому, что, по-видимому, имел в виду ОП. Возможно, я бы использовал оператор switch для установки временной переменной currentColour = red и ' 'после переключения - всего лишь немного меньше повторений. – 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()' is * always * правильный ответ. – 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

Nice. Это именно та логика, которую пыталась реализовать OP. – nnnnnn

2

Другие объяснили Whe вы ошибались, но я думал, что добавлю ответ, чтобы показать, что иногда, когда вы пытаетесь создать массив без дубликатов, проще использовать простой объект в качестве рабочей переменной, а затем просто взять ключи от этого объекта в конце - сохраняет необходимость выполнять любое тестирование того, существует ли какой-либо конкретный элемент.

Если у вас есть:

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

 Смежные вопросы

  • Нет связанных вопросов^_^