Cristian Aleman
Cristian Aleman

Reputation: 19

Is there a better way to use filter array in this case?

I'm trying to implement a function that returns an array.

The goal is to filter an array for getting the yellow fruits, but if there is a Banana then just return all the bananas instead of all the yellow fruits.

My question is if there is another way to enhance this function to avoid filtering twice and just have one filter call.

This is just plain Javascript. I can use the newest features of JS.

let fruits = [
    {name: 'Apple', color: 'Red', size: 'Small'},
    {name: 'Banana', color: 'yellow', size: 'Medium'},
    {name: 'Orange', color: 'orange', size: 'Big'},
    {name: 'Mango', color: 'yellow', size: 'Medium'},
    {name: 'Guava', color: 'yellow', size: 'Medium'},
];

function getFruitsThatAreYellowButReturnOnlyBananaIfExists(fruits)
{
    let yellowFruits = [];

    const bananaFruit = fruits.filter(fruit => fruit.name === "Banana")
        .map(banana => `I'm a banana ${banana.size}`);

    if (bananaFruit.length > 0) {
        return bananaFruit;
    }

    yellowFruits = fruits.filter(fruit => fruit.color === 'yellow')
        .map(yellowFruit => `I'm ${yellowFruit.name} my color is yellow , my size is ${yellowFruit.size}`);

    return yellowFruits;
}

const fruitsOrBanana = getFruitsThatAreYellowButReturnOnlyBananaIfExists(fruits);

I expect the result [ "I'm a banana Medium" ] if there is a banana in the fruits array, and an array of message like this:

[ "I'm Mango my color is yellow , my size is Medium", "I'm Guava my color is yellow , my size is Medium" ]

if there is no banana in the fruits array.

Upvotes: 1

Views: 96

Answers (2)

Shidersz
Shidersz

Reputation: 17190

You can use a for ... of loop to iterate only once over the array of objects. While iterating, you can collect the Bananas in one array and the yellow fruits into another. Then, you can return the array of bananas if there is any, otherwise return the array of yellow fruits.

let fruits=[{name:'Apple',color:'Red',size:'Small'},{name:'Banana',color:'yellow',size:'Medium'},{name:'Orange',color:'orange',size:'Big'},{name:'Mango',color:'yellow',size:'Medium'},{name:'Guava',color:'yellow',size:'Medium'},];

function getFruitsThatAreYellowButReturnOnlyBananaIfExists(fruits)
{
    let yellowFruits = [], bananas = [];

    for (const {name, color, size} of fruits)
    {
        if (name.toLowerCase() === "banana")        
            bananas.push(`I'm a banana ${size}`);
        else if (color.toLowerCase() === "yellow")
            yellowFruits.push(`I'm ${name} my color is yellow , my size is ${size}`);
    }

    return bananas.length ? bananas : yellowFruits;
}

console.log(getFruitsThatAreYellowButReturnOnlyBananaIfExists(fruits));
fruits[1].name = "lemon";
console.log(getFruitsThatAreYellowButReturnOnlyBananaIfExists(fruits));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Upvotes: 1

Michael
Michael

Reputation: 591

One way you could write this that isn't fancy but that would probably be easily understood later on:

const bananas = [];
const yellowFruits = [];

//Only requires 1 loop.
fruit.forEach(f => {
  if (f.name === 'Banana') { 
    bananas.push(`I'm a banana ${f.size}`);
  }
  else if (f.color === 'yellow') { 
    yellowFruits.push(`I'm ${f.name} my color is yellow , my size is ${f.size}`); 
  }
});

if (bananas.length > 0) {
  return bananas;
}
else {
  return yellowFruits;
}


Upvotes: 1

Related Questions