2 回答
TA贡献1884条经验 获得超4个赞
问题在于您的 if 语句的流程。在代码的“onRemove”部分,您说的是“如果成分在列表中,则将其从列表中删除。如果不在,则减少其数量。” 第二部分没有任何意义,更重要的是,你永远也做不到,因为成分应该总是在列表中。
for (let eachIngredient of recipe.ingredients) {
let matched = this.groceryList.find(function(foundIngre) {
return foundIngre.name === eachIngredient.name;
});
if (
matched.name === eachIngredient.name &&
matched._id === eachIngredient._id
) {
let index = this.groceryList.findIndex(
(x) => x._id === matched._id
);
// Problem e ca eachIngredient.quantity se schimba
this.groceryList.splice(index, 1);
} else {
matched.quantity = matched.quantity - eachIngredient.quantity;
}
}
根据你所说的,你想要做的是:
减去归因于已删除配方的数量
如果新数量为零,则从列表中删除该成分(尽管您也可以保留它并忽略数量为零的成分)
试试这个:
for (let eachIngredient of recipe.ingredients) {
// I am assuming that ids are unique so I am not checking foundIngre.name at all,
// since I assume that ingredients with the same name must also have the same name
// I am also using findIndex first so that you don't need a second find when removing
const matchIndex = this.groceryList.findIndex(
(foundIngre) => foundIngre._id === eachIngredient._id
);
if ( matchIndex ) { // this should always be true
const matched = this.groceryList[matchIndex];
// preserve the entry if there is still some quantity
if ( matched.quantity > eachIngredient.quantity ) {
matched.quantity = matched.quantity - eachIngredient.quantity; // can use -= to shorten
}
// remove from the list only if there is no quantity remaining
else {
this.groceryList.splice(matchIndex, 1);
}
}
}
编辑: 尝试更新和删除数组中的项目是一种不必要的痛苦。修改后的代码版本将 _groceryList 存储在键控字典中。我最初打算按成分 ID 键,但在查看您的演示后,我发现我的假设是错误的,即多个食谱中的相同成分将共享相同的 ID。所以我改为按成分名称键入。这样你就可以写入 _groceryList[name] 并且它以前是否存在并不重要。
该类有一个公共的 getter groceryList,它将私有的 _groceryList 字典转换为一个数组。
我还尝试通过使用一个通用toggleIngredient函数来消除场景分支中不必要的代码重复,该函数使用布尔值checked来控制它是通过乘以加号还是减号来控制加法或减法。
import { Component } from "@angular/core";
import { Platform } from "@ionic/angular";
import { SplashScreen } from "@ionic-native/splash-screen/ngx";
import { StatusBar } from "@ionic-native/status-bar/ngx";
import { Subscription } from "rxjs";
export interface Ingredient {
_id: string;
name: string;
quantity: number;
}
export interface Recipe {
_id: string;
name: string;
ingredients: Ingredient[];
}
@Component({
selector: "app-root",
templateUrl: "app.component.html"
})
export class AppComponent {
private _recipesSub: Subscription;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
private loadedRecipes: Recipe[] = [/*...*/]
// store the groceryList in a dictionary keyed by name
private _groceryList: Record<string, Ingredient> = {};
// getter returns the groceryList in array format, ignoring 0 quantities
get groceryList(): Ingredient[] {
return Object.values(this._groceryList).filter( ing => ing.quantity > 0 );
}
// get the current quantity for an ingredient by name, or 0 if not listed
currentQuantity( name: string ): number {
const ingredient = this._groceryList[name];
return ingredient ? ingredient.quantity : 0;
}
// update the quantity for an ingredient when checked or unchecked
// will add new ingredients, but never removes old ones
toggleIngredient( ingredient: Ingredient, checked: boolean ): void {
// add to or remove from quantity depending on the value of checked
const quantity = this.currentQuantity(ingredient.name) + (checked ? 1 : -1 ) * ingredient.quantity;
// replace the object in the grocery list dictionary
this._groceryList[ingredient.name] = {
...ingredient,
quantity
}
}
onCheckRecipe(e) { // you'll want to add a type for e here
for (let recipe of this.loadedRecipes) {
// find the matching recipe
if (recipe.name === e.detail.value) {
// loop through the recipe ingredients
for (let eachIngredient of recipe.ingredients) {
this.toggleIngredient(eachIngredient, e.detail.checked)
}
}
}
}
}
TA贡献1898条经验 获得超8个赞
我认为问题似乎出在代码的这一部分
if (
matched.name === eachIngredient.name &&
matched._id === eachIngredient._id
) {
let index = this.groceryList.findIndex(
(x) => x._id === matched._id
);
// Problem e ca eachIngredient.quantity se schimba
this.groceryList.splice(index, 1);
} else {
matched.quantity = matched.quantity - eachIngredient.quantity;
}
if 语句应该检查数量而不是再次验证名称和 id ,比如
if(matched.quantity <= eachIngredient.quantity){ // 拼接项目并删除它。} else { // 减少数量 }
找到匹配成分的小建议。先用findIndex()检索matchedIndex,再用grocerylist[matchedIndex]检索item,避免再次遍历grocerylist寻找索引进行拼接。
添加回答
举报