最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript reads only first elements(from array) in nested for loops - Stack Overflow

programmeradmin0浏览0评论

I have the following issue. There's a problem I have to solve.

Fruit or Vegetable Write a JS function to print "fruit" , "vegetable" or "unknown" depending on the input string.

  • Fruits are: banana, apple, kiwi, cherry, lemon, grapes, peach

  • Vegetable are: tomato, cucumber, pepper, onion, garlic, parsley

  • All others are unknown

    The input es as array of one string element, the name of the fruit. The output should be printed to the console.

Example: input ['banana'] output: fruit
Example: input ['cucumber'] output: vegetable
Example: input ['pizza'] output: unknown

and I've tried something like that.

function fruitOrVegetable(inputArr) {
  var fruits = ['banana', 'apple', 'kiwi', 'cherry', 'lemon', 'grapes', 'peach'];
  var vegetables = ['tomato', 'cucumber', 'pepper', 'onion', 'garlic', 'parsley'];

  for (var i = 0; i < inputArr.length; i++) {
    for (var j = 0; j < fruits.length; j++) {
      for (var k = 0; k < vegetables.length; k++) {
        if (inputArr[i] === fruits[j]) {
          return ' fruit ';
        } else if (inputArr[i] === vegetables[k]) {
          return 'vegetable';
        } else {
          return 'unknown';
        }
      }
    }
  }
}

console.log(fruitOrVegetable(['tomato'])); //Returns vegetable
console.log(fruitOrVegetable(['banana'])); //Returns fruit
console.log(fruitOrVegetable(['cucumber'])); //Returns unknown
console.log(fruitOrVegetable(['pizza'])); // Returns unknown
console.log(fruitOrVegetable(['appple'])); //Returns unknown

Don't know why , but it works only for the 0 index of the array , for example , for 'tomato' it returns vegetable , but if I try it for the other vegetables , it returns unknown. If I remove that last statement

else{
 return false;
}

Then , cucumber bees vegetable , but apple gots undefined? I'm a bit confused , so I'll be glad if someone explain me why this happens. Thank you.

I have the following issue. There's a problem I have to solve.

Fruit or Vegetable Write a JS function to print "fruit" , "vegetable" or "unknown" depending on the input string.

  • Fruits are: banana, apple, kiwi, cherry, lemon, grapes, peach

  • Vegetable are: tomato, cucumber, pepper, onion, garlic, parsley

  • All others are unknown

    The input es as array of one string element, the name of the fruit. The output should be printed to the console.

Example: input ['banana'] output: fruit
Example: input ['cucumber'] output: vegetable
Example: input ['pizza'] output: unknown

and I've tried something like that.

function fruitOrVegetable(inputArr) {
  var fruits = ['banana', 'apple', 'kiwi', 'cherry', 'lemon', 'grapes', 'peach'];
  var vegetables = ['tomato', 'cucumber', 'pepper', 'onion', 'garlic', 'parsley'];

  for (var i = 0; i < inputArr.length; i++) {
    for (var j = 0; j < fruits.length; j++) {
      for (var k = 0; k < vegetables.length; k++) {
        if (inputArr[i] === fruits[j]) {
          return ' fruit ';
        } else if (inputArr[i] === vegetables[k]) {
          return 'vegetable';
        } else {
          return 'unknown';
        }
      }
    }
  }
}

console.log(fruitOrVegetable(['tomato'])); //Returns vegetable
console.log(fruitOrVegetable(['banana'])); //Returns fruit
console.log(fruitOrVegetable(['cucumber'])); //Returns unknown
console.log(fruitOrVegetable(['pizza'])); // Returns unknown
console.log(fruitOrVegetable(['appple'])); //Returns unknown

Don't know why , but it works only for the 0 index of the array , for example , for 'tomato' it returns vegetable , but if I try it for the other vegetables , it returns unknown. If I remove that last statement

else{
 return false;
}

Then , cucumber bees vegetable , but apple gots undefined? I'm a bit confused , so I'll be glad if someone explain me why this happens. Thank you.

Share Improve this question edited Dec 27, 2016 at 7:08 thefourtheye 240k53 gold badges466 silver badges501 bronze badges asked Dec 27, 2016 at 7:06 Nasco.ChachevNasco.Chachev 6767 silver badges22 bronze badges 4
  • Your discovery - the fact that if you remove the return "unknown"; line, a bunch of these cases work - basically points to the bug here. Try running through your code on the cucumber example and literally go line-by-line like the Javascript interpreter would – disatisfieddinosaur Commented Dec 27, 2016 at 7:09
  • you have to return unknown when the list exhausts – Nagaraju Commented Dec 27, 2016 at 7:11
  • 2 Possible duplicate of How do I check if an array includes an object in JavaScript? – Rajesh Commented Dec 27, 2016 at 7:11
  • check the values in the first iteration, i=0, j=0, k=0 then you have both if and else if returning false so the else block is getting executed with returns unknown – Arun P Johny Commented Dec 27, 2016 at 7:15
Add a ment  | 

7 Answers 7

Reset to default 5

You're doing a massive nested unnecessary for loop there. The task is pretty straightforward

The input es as array of one string element, the name of the fruit. The output should be printed to the console.

You just have to grab that first inputArr value, which is a string and check if its value actually in your fruits, vegetables or else unknown.

Something like,

function fruitOrVegetable(inputArr) {
    var fruits = ['banana', 'apple', 'kiwi', 'cherry', 'lemon', 'grapes', 'peach'];
    var vegetables = ['tomato', 'cucumber', 'pepper', 'onion', 'garlic', 'parsley'];

    var val = inputArr[0];

    return fruits.indexOf(val) !== -1 ? 'fruit' : vegetables.indexOf(val) !== -1 ? 'vegetables' : 'unknown';
}

Edit:

Let's break the code above,

// This is to grab the string from the first value in `inputArr` and store in `val`.
var val = inputArr[0];

And returning,

1 fruits.indexOf(val) !== -1 ? 'fruit' :

2 vegetables.indexOf(val) !== -1 ? 'vegetables' :

3 'unknown';

  1. Check whether val exists in fruits, if it does, return 'fruit' or else run 2
  2. Check whether val exists in vegetables, if it does, return 'vegetables' or else run 3
  3. Return 'undefined'

This operation equals to,

if (fruits.indexOf(val) !== -1) {
    return 'fruit';
}
else if (vegetables.indexOf(val) !== -1) {
    return 'vegetables';
}
else {
    return 'unknown';
}

More info:

?: is a conditional (ternary) operator. (Read more here). It's pretty handy to evaluate expression

e.g.

var myval = 1;
console.log(myval ? 'true' : 'false'); // true

myval = false;
console.log(myval ? 'true' : 'false'); // false

indexOf is an array native function, which you can check the index of a value in an array. (Read more here)

e.g.

var myarr = ['test', 'tost', 'aww'];
console.log(myarr.indexOf('tost')); // returns 1
console.log(myarr.indexOf('tosts')); // returns -1 (value not found)

Suggestions:

  1. Check if the current item is a fruit and only if you made sure that it is not a fruit, check if it is a vegetable.

  2. Return unknown only after confirming if the current item is neither a fruit nor a vegetable.


function fruitOrVegetable(inputArr) {
  var fruits = ['banana', 'apple', 'kiwi', 'cherry', 'lemon', 'grapes', 'peach'];
  var vegetables = ['tomato', 'cucumber', 'pepper', 'onion', 'garlic', 'parsley'];

  var result = [];
  for (var i = 0; i < inputArr.length; i++) {

    var isFruit = false;
    var isVegetable = false;

    for (var j = 0; j < fruits.length; j++) {
      if (inputArr[i] === fruits[j]) {
        result.push('fruit');
        isFruit = true;
        break;
      }
    }

    if (isFruit) {
      // skip rest of the body of the loop as it is a Fruit
      continue;
    }

    for (var j = 0; j < vegetables.length; j++) {
      if (inputArr[i] === vegetables[j]) {
        result.push('vegetable');
        isVegetable = true;
        break;
      }
    }

    if (isVegetable === false) {
      // at this point we know its neither a fruit nor a vegetable
      result.push('unknown');
    }

  }
  return result;
}

console.log(fruitOrVegetable(['tomato', 'banana', 'cucumber', 'pizza', 'apple']));
// [ 'vegetable', 'fruit', 'vegetable', 'unknown', 'fruit' ]

Improvements with Array#indexOf

JavaScript Arrays e with a lot of built-in methods which will help is with basic sorting and searching. You can use the Array.prototype.indexOf to find the index of an element in an array. It will return -1 if it is not found. If we rewrite with that information,

function fruitOrVegetable(inputArr) {
  var fruits = ['banana', 'apple', 'kiwi', 'cherry', 'lemon', 'grapes', 'peach'];
  var vegetables = ['tomato', 'cucumber', 'pepper', 'onion', 'garlic', 'parsley'];

  var result = [];
  for (var i = 0; i < inputArr.length; i += 1) {
    if (fruits.indexOf(inputArr[i]) !== -1) {
      result.push('fruit');
    } else if (vegetables.indexOf(inputArr[i]) !== -1) {
      result.push('vegetable');
    } else {
      result.push('unknown');
    }
  }
  return result;
}

console.log(fruitOrVegetable(['tomato', 'banana', 'cucumber', 'pizza', 'apple']));
// [ 'vegetable', 'fruit', 'vegetable', 'unknown', 'fruit' ]

Improvements with Array#indexOf and Array#map

Now, you can write the same with functional programming approach. You can apply a function to each of the elements of inputArr with Array.prototype.map, like this

function fruitOrVegetable(inputArr) {
  var fruits = ['banana', 'apple', 'kiwi', 'cherry', 'lemon', 'grapes', 'peach'];
  var vegetables = ['tomato', 'cucumber', 'pepper', 'onion', 'garlic', 'parsley'];

  return inputArr.map(function(currentItem) {
    if (fruits.indexOf(currentItem) !== -1) {
      return 'fruit';
    } else if (vegetables.indexOf(currentItem) !== -1) {
      return 'vegetable';
    }
    return 'unknown';
  });
}

console.log(fruitOrVegetable(['tomato', 'banana', 'cucumber', 'pizza', 'apple']));
// [ 'vegetable', 'fruit', 'vegetable', 'unknown', 'fruit' ]

function fruitOrVegetable(inputArr) {
  var fruits = ['banana', 'apple', 'kiwi', 'cherry', 'lemon', 'grapes', 'peach'];
  var vegetables = ['tomato', 'cucumber', 'pepper', 'onion', 'garlic', 'parsley'];
  
  if(inputArr === undefined || !inputArr.length) return 'unknown';

  if(fruits.indexOf(inputArr[0]) !== -1) return 'fruit';
  if(vegetables.indexOf(inputArr[0]) !== -1) return 'vegetable';
  return 'unknown';
}

console.log(fruitOrVegetable(['banana']));
console.log(fruitOrVegetable(['tomato']));
console.log(fruitOrVegetable(['xxx']));
console.log(fruitOrVegetable([]));
console.log(fruitOrVegetable());

Short answer: You have misplaced return "unknown". Consider this:

function fruitOrVegetable(inputArr) {
 var fruits = ['banana', 'apple', 'kiwi', 'cherry', 'lemon', 'grapes', 'peach'];
 var vegetables = ['tomato', 'cucumber', 'pepper', 'onion', 'garlic', 'parsley'];

for (var i = 0; i < inputArr.length; i++) {
  for (var j = 0; j < fruits.length; j++) {
    for (var k = 0; k < vegetables.length; k++) {
      if (inputArr[i] === fruits[j]) {
        return ' fruit ';
      } else if (inputArr[i] === vegetables[k]) {
        return 'vegetable';}
      }
    }
  }
return "unknown";
}

Updated answer according to ments

  1. Don't know why , but it works only for the 0 index of the array

Reason is you are returning value right inside of your loop. So it never runs to the end. To fix that put return "unknown"; outside of the loop.

  1. In general you have messed with loops and code should be simplified. You can ask for code review whenever you think your code can be better, but you don't know how to do that.
  2. It is good practice to simplify code to never get confused with it. For example you could write as below:

     function isVegetable(inputArr)
     {
        var vegetables = ['tomato', 'cucumber', 'pepper', 'onion', 'garlic', 'parsley'];        
    
       for (var i = 0; i < inputArr.length; i++) {
         for (var k = 0; k < vegetables.length; k++) {
            if (inputArr[i] === vegetables[k]) {
              return true;
            }
          }
        }
      return false;
      }
    
    
     function isFruit(inputArr)
     {
          var fruits = ['banana', 'apple', 'kiwi', 'cherry', 'lemon', 'grapes', 'peach'];
    
        for (var i = 0; i < inputArr.length; i++) {
        for (var k = 0; k < fruits.length; k++) {
            if (inputArr[i] === fruits[k]) {
                return true;
                }
            }
         }
        return false;
     }
    
     function fruitOrVegetable(inputArr)
     {
         if(isVegetable(inputArr)) return "vegetable";  
         if(isFruit(inputArr)) return "fruit";
         return "unknown";
     }
    

First of all return vegetable is the reason why it's only working for index 0. Because after first loop it returns a value and function ends. Instead initialize outputArray at start and set values to that array outputArray[i] = 'veg' and at the end return outputArray
Next thing is don't nest too much loops within each other. Instead use check for veg or fruit separately inside large for loop:
for() {...} for() {...}
Sorry couldn't plete codes cause I'm writing from my phone

You can try this way if it wil be preferable to you:-

function fruitOrVegetable(inputArr) {
  var fruits = ['banana', 'apple', 'kiwi', 'cherry', 'lemon', 'grapes', 'peach'];
  var vegetables = ['tomato', 'cucumber', 'pepper', 'onion', 'garlic', 'parsley'];

  if ( fruits.indexOf( inputArr[0] ) > -1 ){
     return 'fruits';
  }else if ( vegetables.indexOf( inputArr[0] ) > -1 ){
     return 'vegetable';
  }else{
     return 'unknown';
  }
}

Modify your code like this, it will work file.

function fruitOrVegetable(inputArr) {

    var fruits = ['banana' , 'apple' , 'kiwi' , 'cherry' , 'lemon' , 'grapes' , 'peach'];
    var vegetables = ['tomato' , 'cucumber' , 'pepper' , 'onion' , 'garlic' , 'parsley'];

    for(var i = 0 ; i < inputArr.length ; i++)
    {
        for(var j = 0 ; j < fruits.length ; j++)
        {
            if(inputArr[i] === fruits[j]){
                    return ' fruit ';
                    }
        }
        for(var k = 0 ; k < vegetables.length ; k++)
        {

                 if(inputArr[i] === vegetables[k]){
                    return 'vegetable';
                }

        }

    }
                  return 'unknown';
}  

Result:

fruitOrVegetable(['tomato']); "vegetable" fruitOrVegetable(['banana']); " fruit "

fruitOrVegetable(['qwe']); "unknown"

发布评论

评论列表(0)

  1. 暂无评论