Nested loops with arrays not working as expected

Viewed 48

I am trying to accomplish the following...

Given the array cakes as:

const cakes = [
    {id: 1, name: 'chocolate'},
    {id: 2, name: 'strawberry'},
    {id: 3, name: 'mint'}
]

And the array 'favorite cakes' as:

const favCakes = [
    {id: 1, cakeId: 1},
    {id: 2, cakeId: 2}
]

I want to log FAVORITE CAKES and NOT FAVORITE CAKES on console so I would expect a result like this:

FAVORITE CAKES: 'chocolate'
FAVORITE CAKES: 'strawberry'
NOT FAVORITE CAKES: 'mint'

But it does't work as expected as you can see from the snippet below. What am I doing wrong? I appreciate any help.

const cakes = [
    {id: 1, name: 'chocolate'},
    {id: 2, name: 'strawberry'},
    {id: 3, name: 'mint'}
]

// favorite cakes for logged in user
const favCakes = [
    {id: 1, cakeId: 1},
    {id: 2, cakeId: 2}
]

for (const cake of cakes) {
    for (const fav of favCakes) {
        if (cake.id === fav.cakeId) {
            console.log('FAVORITE CAKE: ', cake.name )
        }
        else if (cake.id !== fav.cakeId) {
            console.log('NOT FAVORITE CAKE: ', cake.name )
        }
    }
}

5 Answers

You are checking for not-favorites too early. You can only determine not-favorites after you have looked through all the favorites:

for (const cake of cakes) {
    let isFavorite = false; // assume

    for (const fav of favCakes) {
        if (cake.id === fav.cakeId) {
            console.log('FAVORITE CAKE: ', cake.name)
            isFavorite = true;
            break;
        }
    }

    if ( ! isFavorite ) {
        console.log( 'NOT FAVORITE CAKE: ', cake.name )
    }

}

You can use forEach & find. Use forEach to iterate the cakes array and use its id to find the object with same id in favCakes. If the id matches then log the name with favorite else with not favorite

const cakes = [{
    id: 1,
    name: 'chocolate'
  },
  {
    id: 2,
    name: 'strawberry'
  },
  {
    id: 3,
    name: 'mint'
  }
]

const favCakes = [{
    id: 1,
    cakeId: 1
  },
  {
    id: 2,
    cakeId: 2
  }
]

cakes.forEach((item) => {
  const isFav = favCakes.find(elem => elem.id === item.id)
  if (isFav) {
    console.log('Fav cake ', item.name)
  } else {
    console.log('Not Fav cake ', item.name)
  }

})

You need to keep track of whether the cake was found in your favorites list. Then, after looking through all the favorites, you can report on whether it was found.

const cakes = [
    {id: 1, name: 'chocolate'},
    {id: 2, name: 'strawberry'},
    {id: 3, name: 'mint'}
]

// favorite cakes for logged in user
const favCakes = [
    {id: 1, cakeId: 1},
    {id: 2, cakeId: 2}
]

for (const cake of cakes) {
    let foundAsFavorite = false
    
    for (const fav of favCakes) {
        if (cake.id === fav.cakeId) {
            foundAsFavorite = true
        }
    }

    if (foundAsFavorite) {
        console.log('FAVORITE CAKE: ', cake.name )
    }
    else {
        console.log('NOT FAVORITE CAKE: ', cake.name )
    }
}

Here's a simpler solution that uses the Array.some function to find out if any favorites match your cake:

const cakes = [
    {id: 1, name: 'chocolate'},
    {id: 2, name: 'strawberry'},
    {id: 3, name: 'mint'}
]

// favorite cakes for logged in user
const favCakes = [
    {id: 1, cakeId: 1},
    {id: 2, cakeId: 2}
]

for (const cake of cakes) {
    const foundAsFavorite = favCakes.some(fav => cake.id === fav.cakeId)

    if (foundAsFavorite) {
        console.log('FAVORITE CAKE: ', cake.name )
    }
    else {
        console.log('NOT FAVORITE CAKE: ', cake.name )
    }
}

You shouldn't do it nested - use a method such as some inside a forEach instead, and simplify with destructuring:

const cakes = [
    {id: 1, name: 'chocolate'},
    {id: 2, name: 'strawberry'},
    {id: 3, name: 'mint'}
]

// favorite cakes for logged in user
const favCakes = [
    {id: 1, cakeId: 1},
    {id: 2, cakeId: 2}
]

cakes.forEach(({ id, name }) => {
    if (!favCakes.some(({ cakeId }) => cakeId == id)) {
      console.log("NOT FAVOURITE CAKE: " + name);
    } else {
      console.log("FAVOURITE CAKE: " + name);
    }
});

you can create a lookup list like this.

    const cakes = [{
        id: 1,
        name: 'chocolate'
      },
      {
        id: 2,
        name: 'strawberry'
      },
      {
        id: 3,
        name: 'mint'
      }
    ];

    // favorite cakes for logged in user
    const favCakes = [{
        id: 1,
        cakeId: 1
      },
      {
        id: 2,
        cakeId: 2
      }
    ];

    const favCakeIds = favCakes.map(c => c.cakeId);

    for (const cake of cakes) {
      if (favCakeIds.includes(cake.id)) {
        console.log('FAVORITE CAKE: ' + cake.name)
      } else {
        console.log('NOT FAVORITE CAKE: ' + cake.name)
      }
    }

Related