2

How can i check the available data from two array and return new array. For example i want to compare data from one array and check with another array and if it available then it will return with new array with count . Below is the two array and my expected result code.

        const restaurant = [
                { name: 'La mesa', cuisine: ['chiness', 'arabic'] },
                { name: 'Purnima', cuisine: ['thai'] },
                { name: 'Red Bull', cuisine: ['french', 'arabic'] },
                { name: 'Pasta', cuisine: ['indian'] },
            ];

            const cuisine = [
                { name: 'chiness' },
                { name: 'arabic' },
                { name: 'thai' },
                { name: 'french' },
                { name: 'italian' },
                { name: 'indian' },
                { name: 'mexican' },
            ];

            // Expected Output a new array like this below
            const myCuisine = [
                { name: 'chiness', restaurant: 1 },
                { name: 'arabic', restaurant: 2 },
                { name: 'thai', restaurant: 1 },
                { name: 'french', restaurant: 1 },
                { name: 'italian', restaurant: 0 },
                { name: 'indian', restaurant: 1 },
                { name: 'mexican', restaurant: 0 },
            ];

Thank you

1
  • Please add the code you've tried Commented Sep 5, 2020 at 11:24

6 Answers 6

2

You can use the functions map, reduce, and some all together to build the desired output as follow:

const restaurant = [    { name: 'La mesa', cuisine: ['chiness', 'arabic'] },    { name: 'Purnima', cuisine: ['thai'] },    { name: 'Red Bull', cuisine: ['french', 'arabic'] },    { name: 'Pasta', cuisine: ['indian'] }],
      cuisine = [    { name: 'chiness' },    { name: 'arabic' },    { name: 'thai' },    { name: 'french' },    { name: 'italian' },    { name: 'indian' },    { name: 'mexican' }],
      myCuisine = cuisine.map(({name}) => ({name, restaurant: restaurant.reduce((r, {cuisine}) => r + cuisine.some(c => c === name) , 0)}));

console.log(myCuisine)
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

Comments

1

With map and filter, this way:

const myCuisine = cuisine.map(
  item => {
    return {
      ...item,
      restaurant: restaurant.filter(
        res => res.cuisine.indexOf(item.name) >= 0
      ).length
    }
  }
);

1 Comment

Using the function filter for counting should be avoided.
1

You can map the cuisines and filter the restaurants to get the number of restaurants

cuisine.map((cuisineObject) => {
  const numberOfRestaurants = restaurant.filter((restaurantObject) => restaurantObject.cuisine.includes(cuisineObject.name)).length
    return {
        ...cuisineObject,
        restaurant: numberOfRestaurants
    }
})

1 Comment

Using the function filter for counting should be avoided.
0

First we can format the restaurants with cuisine information into an object and then use the same object for finding out the number of restaurants serving the particular cuisine. This can be achieved using Array.reduce and Array.map.

const restaurant = [{name:'La mesa',cuisine:['chiness','arabic']},{name:'Purnima',cuisine:['thai']},{name:'Red Bull',cuisine:['french','arabic']},{name:'Pasta',cuisine:['indian']}];

const cuisine = [{name:'chiness'},{name:'arabic'},{name:'thai'},{name:'french'},{name:'italian'},{name:'indian'},{name:'mexican'}];

const getFormattedList = (cuisines, restaurants) => {
  return cuisines.map(cuisine => {
    return {
      ...cuisine,
      restaurant: restaurants[cuisine.name] || 0
    }
  })
}

const formatRestaurantCuisines = (restaurants) => {
  return restaurants.reduce((result, restaurant) => {
    restaurant.cuisine.forEach(cuisine => {
        result[cuisine] = (result[cuisine]||0) + 1;
    })
    return result;
  }, {});
}

//Formatted object to convert the restaurant with cuisine info to count
const formattedObj = formatRestaurantCuisines(restaurant);
console.log(formattedObj);
console.log(getFormattedList(cuisine, formattedObj))
.as-console-wrapper {
   max-height: 100% !important;
}

Comments

0

You can build an object which stores all the frequencies of each cuisine with .reduce() and then use .map() on your cuisine array like so:

const restaurant = [ { name: 'La mesa', cuisine: ['chiness', 'arabic'] }, { name: 'Purnima', cuisine: ['thai'] }, { name: 'Red Bull', cuisine: ['french', 'arabic'] }, { name: 'Pasta', cuisine: ['indian'] }, ]; 
const cuisine = [ { name: 'chiness' }, { name: 'arabic' }, { name: 'thai' }, { name: 'french' }, { name: 'italian' }, { name: 'indian' }, { name: 'mexican' }, ];

const cusineFreq = restaurant.reduce((o, {cuisine}) => {
  cuisine.forEach(type => o[type] = (o[type] || 0) + 1);
  return o;
}, {}); 
const res = cuisine.map(o => ({...o, restaurant: (cusineFreq[o.name] || 0)}));
console.log(res);

This approach of creating an object for look-up is particularly useful if restaurant is large, as it allows for a time complexity of O(n + k) rather than O(n*k). Thus, it will allow for better overall performance compared to nested loops and is more scalable.

Comments

0

Using map, flatMap and filter

Edited: using flatMap instead of map.flat

cuisine.map(({name}) => ({name: name,restaurant: restaurant.flatMap(v => v.cuisine).filter(v=>v === name).length}))

5 Comments

Using the function filter for counting should be avoided.
@Ele what would be better?
You could use .flatMap() instead of .map().flat()
@NickParsons thats interesting!
@RadicalEdward reduce is a better approach because you avoid creating an array which is the case of using the function filter.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.