【问题标题】:Compare two array object for matched data and return new array object比较两个数组对象的匹配数据并返回新的数组对象
【发布时间】:2020-09-05 10:56:09
【问题描述】:

如何检查两个数组中的可用数据并返回新数组。例如,我想比较一个数组中的数据并检查另一个数组,如果它可用,那么它将返回带有 count 的新数组。下面是两个数组和我预期的结果代码。

        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 },
            ];

谢谢

【问题讨论】:

  • 请添加您尝试过的代码

标签: javascript arrays filter


【解决方案1】:

您可以一起使用函数map、reduce 和some 来构建所需的输出,如下所示:

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

【讨论】:

    【解决方案2】:

    使用地图和过滤器,这样:

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

    【讨论】:

    • 应避免使用函数filter进行计数。
    【解决方案3】:

    您可以映射美食并过滤餐厅以获得餐厅数量

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

    【讨论】:

    • 应避免使用函数filter进行计数。
    【解决方案4】:

    首先,我们可以将带有美食信息的餐厅格式化为一个对象,然后使用同一个对象找出供应特定美食的餐厅数量。这可以使用Array.reduce 和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;
    }

    【讨论】:

      【解决方案5】:

      您可以使用.reduce() 构建一个存储每种美食的所有频率的对象,然后在您的cuisine 数组上使用.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 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);

      如果restaurant 很大,这种创建用于查找的对象的方法特别有用,因为它允许 O(n + k) 而不是 O(n*k) 的时间复杂度。因此,与嵌套循环相比,它可以提供更好的整体性能,并且更具可扩展性。

      【讨论】:

        【解决方案6】:

        使用map、flatMap 和filter

        已编辑:使用flatMap 而不是map.flat

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

        【讨论】:

        • 应避免使用函数filter进行计数。
        • @Ele 什么会更好?
        • 你可以用.flatMap()代替.map().flat()
        • @NickParsons 这很有趣!
        • @RadicalEdward reduce 是一种更好的方法,因为您可以避免创建数组,这是使用函数 filter 的情况。
        猜你喜欢
        • 2022-01-02
        • 2021-02-04
        • 1970-01-01
        • 1970-01-01
        • 2018-05-18
        • 1970-01-01
        • 2020-09-26
        • 2020-08-17
        • 1970-01-01
        相关资源
        最近更新 更多