为了账号安全,请及时绑定邮箱和手机立即绑定

通过检查另一个带有对象的嵌套数组来过滤带有对象的嵌套数组

通过检查另一个带有对象的嵌套数组来过滤带有对象的嵌套数组

呼如林 2022-07-08 10:02:11
我有一个这样的数组:const state = {  products: [    { name: "Potato", amount: "3"},    { name: "Butter", amount: "1000" },    { name: "Salt", amount: "2000" },    //{name: "Egg", amount: "10"},    { name: "Tomato",  amount: "5"},    { name: "Sour Milk", amount: "5"}  ],  recipes: [    {      name: "Mashed potatoes",      ingredients: [        { name: "Potato", amount: "5"},        { name: "Butter", amount: "30"},        { name: "Salt", amount: "15"}      ],      instructions: "Some Text"    },    {      name: "Tomato Omelette",      ingredients: [        { name: "Tomato", amount: "1" },        { name: "Egg", amount: "1" },        { name: "Salt", amount: "10" },        { name: "Butter", amount: "40" }      ],      instructions: "Some text"    }  ]};我想按我可以用我的产品烹饪的食谱过滤我的食谱数组(在这种情况下,我不能做“番茄煎蛋卷”,因为我没有鸡蛋,也不能做“土豆泥”,因为我没有没有足够的土豆)。到目前为止,我尝试了不同的方法,但我没有想出一个完整的解决方案。我最接近的解决方案是:const filterRecipes = (filter, products, recipes) => {  if(filter === 'available products') {      //Getting all product names for future tests      const productsNames = products.map(item => item.name);      //Here we will filter all our recipes by available products       const result = recipes.filter(recipe => {          //Getting all ingredient names of the current recipe          const ingredientNames = recipe.ingredients.map(item => item.name);          //If we have all products for our recipe          //we will add it to our filtered array          if (ingredientNames.every((name) => productsNames.includes(name))){              return true;          }      })      console.log(result);  }};这仅适用于产品名称,但不适用于其数量。当我试图检查它刚刚打破的金额时。
查看完整描述

3 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

我们可以这样做:

  • 设置一个productsObjwith reduce 以允许快速查找

  • 过滤食谱数组

  • 在食谱过滤器函数的每个回调中,并循环每个食谱的成分

  • 对于每种成分,检查它是否存在productsObj并且数量大于或等于配方成分中的项目。

  • 如果它存在并且数量足够大,请继续检查其余成分

  • 如果不是,则返回 false - 即过滤出数组。

const state = {

  products: [

    { name: "Potato", amount: "5" },

    { name: "Butter", amount: "1000" },

    { name: "Salt", amount: "2000" },

    { name: "Egg", amount: "10" },

    { name: "Tomato", amount: "5" },

    { name: "Sour Milk", amount: "5" }

  ],

  recipes: [

    {

      name: "Mashed potatoes",

      ingredients: [

        { name: "Potato", amount: "5" },

        { name: "Butter", amount: "30" },

        { name: "Salt", amount: "15" }

      ],

      instructions: "Some Text"

    },

    {

      name: "Tomato Omelette",

      ingredients: [

        { name: "Tomato", amount: "1" },

        { name: "Egg", amount: "1" },

        { name: "Salt", amount: "10" },

        { name: "Butter", amount: "40" }

      ],

      instructions: "Some text"

    }

  ]

};


const filterRecipes = (filter, products, recipes) => {

  if (filter === "available products") {

    //Getting all product names in an object for fast look-up

    const productsObj = products.reduce((aggObj, item) => {

      aggObj[item.name] = item;

      return aggObj;

    }, {});

    //console.log("o", productsObj);


    //Here we will filter all our recipes by available products

    const result = recipes.filter((recipe) => {

      let valid = true; //true until proven false


      //Loop over ingredients of each recipe

      for (let i = 0; i < recipe.ingredients.length; i++) {

        const item = recipe.ingredients[i];

        const lookup = productsObj[item.name] || false;

        const quantityEnough = lookup

          ? parseInt(lookup.amount) >= parseInt(item.amount)

          : false;

        if (!quantityEnough) {

          valid = false;

          break;

        }

      }

      return valid;

    });

    console.log(result);

  }

};


filterRecipes("available products", state.products, state.recipes);

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


例如,如果您将产品数量更改为:


const state = {

  products: [

    { name: "Potato", amount: "4" },

    { name: "Butter", amount: "1000" },

    { name: "Salt", amount: "2" },

    { name: "Egg", amount: "10" },

    { name: "Tomato", amount: "5" },

    { name: "Sour Milk", amount: "5" }

  ],

你没有得到任何结果,因为盐和土豆的数量对于任何一种食谱都不够大。


查看完整回答
反对 回复 2022-07-08
?
跃然一笑

TA贡献1826条经验 获得超6个赞

您可以使用对象以更快地访问,并使用amount数字以获得更好的可比性


{

    Potato: 5,

    Butter: 1000,

    Salt: 2000,

    Tomato: 5,

    "Sour Milk": 5

}

并且只循环产品和收据一次。


这种方法使用解构赋值,其中属性从对象中取出。


它使用对象的值并检查所有成分的可用量。


const

    filter = ({ products, recipes }) => {

        const avalilable = products.reduce((r, { name, amount }) => (r[name] = +amount, r), {});

console.log(avalilable )

        return recipes.filter(({ ingredients }) =>

            ingredients.every(({ name, amount }) => avalilable[name] >= +amount));

    },

    state = { products: [{ name: "Potato", amount: "5" }, { name: "Butter", amount: "1000" }, { name: "Salt", amount: "2000" }, { name: "Tomato", amount: "5" }, { name: "Sour Milk", amount: "5" }], recipes: [{ name: "Mashed potatoes", ingredients: [{ name: "Potato", amount: "5" }, { name: "Butter", amount: "30" }, { name: "Salt", amount: "15" }], instructions: "Some Text" }, { name: "Tomato Omelette", ingredients: [{ name: "Tomato", amount: "1" }, { name: "Egg", amount: "1" }, { name: "Salt", amount: "10" }, { name: "Butter", amount: "40" }], instructions: "Some text" }] },

    recipes = filter(state);


console.log(recipes);


查看完整回答
反对 回复 2022-07-08
?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

你可以试试这个解决方案。


在这里,我添加了一种解决方案,例如,您有“盐”20单位,而第一个食谱采用它们的单位进行烹饪。15


现在假设,第二个配方需要10单位的盐,但你5的商店里还有单位。在这种情况下,您不能采用第二种烹饪方法。


const state = {

  products: [

    { name: "Potato", amount: "5"},

    { name: "Butter", amount: "1000" },

    { name: "Salt", amount: "20" },

    { name: "Egg", amount: "1"},

    { name: "Tomato",  amount: "5"},

    { name: "Sour Milk", amount: "5"}

  ],

  recipes: [

    {

      name: "Mashed potatoes",

      ingredients: [

        { name: "Potato", amount: "5"},

        { name: "Butter", amount: "30"},

        { name: "Salt", amount: "15"}

      ],

      instructions: "Some Text"

    },

    {

      name: "Tomato Omelette",

      ingredients: [

        { name: "Tomato", amount: "1" },

        { name: "Egg", amount: "1" },

        { name: "Salt", amount: "10" },

        { name: "Butter", amount: "40" }

      ],

      instructions: "Some text"

    }

  ]

};



const filterRecipes = (filter, products, recipes) => {

    if (filter === 'available products') {

        

        /**

        * Restructure the products from array to object.

        * like {Potato: "20", "Salt": "200"}

        */

        const store = products.reduce((a, {name, amount}) => {

            return {...a, [name]: amount};

        }, {});

        

        

        const canCook = recipes.filter(recipe => {

            /**

            * Convert ingredient from array to object like products

            *

            */

            const ingredients = recipe.ingredients.reduce((a, {name, amount}) => {

                return {...a, [name]: amount};

            }, {});

            

            /**

            * Check if every ingredients are available at the store

            */

            const allow = Object.entries(ingredients).every(([name, amount]) => {

                return (store[name] !== undefined && (+store[name]) >= (+amount));

            });


            /**

            * This is for reducing the amount of ingredient from the store

            * if the recipe is taken for cooking.

            * You can omit it if you don't need to measure this factor.

            */

            if (allow) {

                Object.entries(ingredients).forEach(([name, amount]) => {

                    store[name] -= amount;

                });

            }

            

            return allow;

        });

        

        console.log(canCook);

    }

}


filterRecipes("available products", state.products, state.recipes);

.as-console-wrapper {min-height: 100% !important; top: 0;}


查看完整回答
反对 回复 2022-07-08
  • 3 回答
  • 0 关注
  • 164 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号