Diego
Diego

Reputation: 268

Nested loops with arrays not working as expected

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 )
        }
    }
}

Upvotes: 2

Views: 54

Answers (5)

Jack Bashford
Jack Bashford

Reputation: 44107

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);
    }
});

Upvotes: 1

D. Seah
D. Seah

Reputation: 4592

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)
      }
    }

Upvotes: 0

Cully
Cully

Reputation: 6965

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 )
    }
}

Upvotes: 2

brk
brk

Reputation: 50291

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)
  }

})

Upvotes: 3

kmoser
kmoser

Reputation: 9273

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 )
    }

}

Upvotes: 3

Related Questions