0

Im learning Javascript and facing trouble with an exercise.

By using array.map() method (and .filter()method). I have to modify this array of object:

var cakes = [
    {
        name: "cake",
        flavor: "vanilla",
        status: "available"
    },
    {
        name: "brownie",
        flavor: "chocolate",
        status: "available"
    },
    {
        name: "pie",
        flavor: "strawberry",
        status: "available"
    },
    {
        name: "muffin",
        flavor: "pistachio",
        status: "available"
    },
    {
        name: "donut",
        flavor: "chocolate",
        status: "available"
    },
];

The modification is to set the status of all chocolate cakes in sold out.

For now I've tried several hypothesis. The meaningful one for me, was to put an other iteration with a "for" to ask the method to iterate on the different cakes and modify the status if the flavor was chocolate, but I understand that it's not needed. the method is alreaydy doing it.

I came back to an easier way to do things :

var soldOut1=cakes.map(function(cake){
    if(cake.flavor==="chocolate"){
        return cake.status="sold out";
}
else{return cake;}
});
console.log(soldOut1);

This gave me the most successful result:

[
  { name: 'cake', flavor: 'vanilla', status: 'available' },
  'sold out',
  { name: 'pie', flavor: 'strawberry', status: 'available' },
  { name: 'muffin', flavor: 'pistachio', status: 'available' },
  'sold out'
]

But as you may see, and Im sure it's pretty logical, but I can't keep the other properties for brownie and donut cakes. Im trying to understand the .map() method's limit. So is it possible to do that kind of work with a .map() method exclusievely?

tadman
  • 208,517
  • 23
  • 234
  • 262
Dimah
  • 1
  • 2
    PSA: It's 2023 and it's time to start using `const` and `let` instead of the troublesome `var`. – tadman Feb 02 '23 at 17:39
  • 1
    Relevant: [What is the concept of Array.map?](https://stackoverflow.com/q/17367889) – VLAZ Feb 02 '23 at 17:39
  • I'm not sure you're doing this right. I'd consider: `{ ...cake, status: 'sold out' }` by employing the [spread operator `...`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) to override a single property. This is also a lot cleaner with the [`=>` arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) notation. – tadman Feb 02 '23 at 17:41
  • 1
    The purpose of [`Array.map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) is to walk the array and produce another array of the same size. Each item of the new array is produced from the corresponding item of the original array. [`Array.filter()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) produces a new array whose items are a subset of the items of the original array. None of them qualifies for the description _"modifying arrays"_. – axiac Feb 02 '23 at 17:44
  • If you need to modify the elements of the array then you can use `Array.push()`, `Array.pop()`, `Array.splice()` or other [methods that mutate the array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#copying_methods_and_mutating_methods) or to assign new values by [accessing the array items by index](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#access_an_array_item_by_its_index). – axiac Feb 02 '23 at 17:49
  • If you do not want to modify the array but the properties of its items (assuming that the items are objects) then the method that you are looking for is [`Array.forEach()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach). – axiac Feb 02 '23 at 17:49

3 Answers3

2

Please update you status first then return the element:

var soldOut1=cakes.map(function(cake){
    if(cake.flavor==="chocolate"){
        cake.status="sold out";
        return cake;
}
else{return cake;}
});
console.log(soldOut1);
0

If you do not want to modify the array but the properties of its items (assuming that the items are objects) then the method that you are looking for is Array.forEach().

const cakes = [{
    name: "cake",
    flavor: "vanilla",
    status: "available"
  },
  {
    name: "brownie",
    flavor: "chocolate",
    status: "available"
  },
  {
    name: "pie",
    flavor: "strawberry",
    status: "available"
  },
  {
    name: "muffin",
    flavor: "pistachio",
    status: "available"
  },
  {
    name: "donut",
    flavor: "chocolate",
    status: "available"
  },
];

cakes.forEach((cake) => {
  if (cake.flavor === 'chocolate') {
    cake.status = 'sold out';
  }
});

console.log(cakes);

If you insist on using Array.map(), it produces a new array that you can then store in the same variable (loosing the original) or in a new variable:

let cakes = [{
    name: "cake",
    flavor: "vanilla",
    status: "available"
  },
  {
    name: "brownie",
    flavor: "chocolate",
    status: "available"
  },
  {
    name: "pie",
    flavor: "strawberry",
    status: "available"
  },
  {
    name: "muffin",
    flavor: "pistachio",
    status: "available"
  },
  {
    name: "donut",
    flavor: "chocolate",
    status: "available"
  },
];

cakes = cakes.map((cake) => {
  return {
    ... cake,
    status: cake.flavor === 'chocolate' ? 'sold out': cake.status,
  };
});

console.log(cakes);

Please note that, while on the first example cakes is declared as const (the name cakes is associated with an initial value and the association cannot change), on the second example it has to be declared using let, otherwise it cannot be associated with the value returned by Array.map() (which is a new array).

axiac
  • 68,258
  • 9
  • 99
  • 134
0

You can destructure the flavor and status for each "pastry" and map the status based on the flavor being "chocolate" or not.

const pastries = [
  { name: "cake"    ,  flavor: "vanilla"    ,  status: "available" },
  { name: "brownie" ,  flavor: "chocolate"  ,  status: "available" },
  { name: "pie"     ,  flavor: "strawberry" ,  status: "available" },
  { name: "muffin"  ,  flavor: "pistachio"  ,  status: "available" },
  { name: "donut"   ,  flavor: "chocolate"  ,  status: "available" },
];

const result = pastries.map(({ flavor, status, ...pastry }) => ({
  ...pastry,
  flavor,
  status: flavor === 'chocolate' ? 'sold out' : status
}));

console.log(result);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132