3 回答

TA貢獻1816條經驗 獲得超6個贊
我們可以這樣做:
設置一個
productsObj
with 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" }
],
你沒有得到任何結果,因為鹽和土豆的數量對于任何一種食譜都不夠大。

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

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;}
添加回答
舉報