0

All I'm trying to do is filter a list of stores, store it in a new variable object called grapefruitStores, and print it to the console in JavaScript. I'm allowed to use filter, map, and reduce. Here's what I have so far:

const stores = [{
   name: "Kents",
   foods: [
       {name: 'bagels', type: 'grain'},
       {name: 'bread', type: 'grain'},
       {name: 'cereal', type: 'grain'},
       {name: 'milk', type: 'dairy'},
   ]
   },{
   name: "Maceys",
   foods: [
       {name: 'bagels', type: 'grain'},
       {name: 'bread', type: 'grain'},
       {name: 'cereal', type: 'grain'},
       {name: 'grapefruit', type: 'fruit'},
       {name: 'milk', type: 'dairy'},
   ]
}];

//Filtering code

function sellsGrapefruit(stores) {
   return stores.foods.name === 'grapefruit'; //Don't think this is correct.
}

var grapefruitStores = store.filter(sellsGrapefruit);

console.log(grapefruitStores);

So, only the Maceys object information should print to the console since Maceys sells grapefruit and Kents does not. An empty array/object keeps printing to the screen, and I'm not sure why. What am I doing wrong here? Any help would be appreciated.

3
  • foods is array in each one...an array can't have a property name. Need to iterate the foods array Commented Jan 19, 2017 at 0:35
  • Yeah, I figured. How would I do that? Commented Jan 19, 2017 at 0:37
  • Filter will iterate over them for you. store.foods.filter(function(food) { return food.name === 'grapefruit'; }) Commented Jan 19, 2017 at 0:53

5 Answers 5

4

You can use Array.some():

function sellsGrapefruit(store) {
    return store.foods.some(function(food) {
        return food.name === 'grapefruit';
    });
};

var grapefruitStores = stores.filter(sellsGrapefruit);
Sign up to request clarification or add additional context in comments.

3 Comments

In this case, I don't think they're allowed to. "I'm allowed to use filter, map, and reduce."
Thank you, @Washington Guedes!
I like your answer. I was not aware of the Array.some() function.
0

There's a little flaw with your filter logic. Your algorithm is checking the foods attribute of the stores array. It should be checking the foods attribute of each element in the stores array. Try this:

//Filtering code
function sellsGrapefruit(store) {
  for (var i in store.foods) {
    var food = store.foods[i];
    if (food.name === 'grapefruit')
      return true;
  }
  return false;
}

Here is a working example:

jsFiddle: https://jsfiddle.net/mspinks/8vzfc8uL/3/

Comments

0

So this is pretty simple with the filter method. What this does is include elements from an array depending on the boolean return value of the function passed to it. You're almost there with what you posted, but foods is an array of objects, each of which has a name property, and you're currently calling the (non-existent) name property of stores.

So for this example, with working iteration, a working solution would be:

var grapefruitStores = stores.filter(function(store) {
    for (var i = 0; i < store.foods.length; i++) {
        if (store.foods[i].name === 'grapefruit') {
            return true;
        }
    }
});

4 Comments

Why are you using a for loop inside filter when you can use filter again. Edit, oh to exit early. I guess that's valid, but probably besides the point of learning filter/map/reduce
Because I didn't want to use filter again? I'm not sure why you think I should use one or the other. If anything, the for loop is faster.
Thank you, @furkle!
@WashingtonGuedes Good point! And also you're right, that's a typo on my part, thanks.
0

Foods arrays is nested in the objects in the stores array, so you have to use the filter twice in order to get the result you want:

const stores = [{
   name: "Kents",
   foods: [
       {name: 'bagels', type: 'grain'},
       {name: 'bread', type: 'grain'},
       {name: 'cereal', type: 'grain'},
       {name: 'milk', type: 'dairy'}
   ]
   },{
   name: "Maceys",
   foods: [
       {name: 'bagels', type: 'grain'},
       {name: 'bread', type: 'grain'},
       {name: 'cereal', type: 'grain'},
       {name: 'grapefruit', type: 'fruit'},
       {name: 'milk', type: 'dairy'}
   ]
}];

function sellsGrapefruit(store) {
    var x = store.foods.filter(function(i) {
        return i.name === 'grapefruit';
    });
    return x.length > 0;
}

var grapefruitStores = stores.filter(sellsGrapefruit); // typo error: store -> stores

console.log(grapefruitStores[0]);

Comments

0

Since you're allowed to use only map, reduce, filter. I took this approach.

var grapeStores = stores.filter(function (store) {
  return store.foods.filter(function (food) {
    return food.name === 'grapefruit';
  }).length;
});

console.log('grapeStores', grapeStores);

It logs

grapeStores [ { name: 'Maceys',
    foods: [ [Object], [Object], [Object], [Object], [Object] ] } ]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.