亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

刪除對象項并將其添加到數組中,如果數組中已存在特定項,則更改對象鍵

刪除對象項并將其添加到數組中,如果數組中已存在特定項,則更改對象鍵

炎炎設計 2023-03-24 15:39:38
我有這個食譜數組,其中每個對象都是一個特定的食譜,每個食譜都有一個成分數組,每個成分都是由_id name quantity. 如果你們知道為什么會這樣,請在下面添加我的問題,請告訴我。我掙扎了 3 天......任何建議將不勝感激。多謝!(3) [{…}, {…}, {…}]0:ingredients: Array(4)0: {_id: "5f6628d0029e87e02c79ce0a", name: "chia", quantity: 10}1: {_id: "5f6628d0029e87e02c79ce0b", name: "apple", quantity: 15}2: {_id: "5f6628d0029e87e02c79ce0c", name: "honey", quantity: 30}3: {_id: "5f6628d0029e87e02c79ce0d", name: "almond flour", quantity: 35}length: 4__proto__: Array(0)name: "Coconut Chia Pudding"__v: 0_id: "5f6628d0029e87e02c79ce09"__proto__: Object1: {_id: "5f6628d0029e87e02c79ce0e", name: "Peanut Butter Cookies", ingredients: Array(4), __v: 0}2: {_id: "5f6628d0029e87e02c79ce13", name: "Caprese Avocado Bowls", ingredients: Array(3), __v: 0}length: 3__proto__: Array(0)我在 UI 中擁有的是一個包含上述食譜的列表,用戶可以勾選和取消勾選,在勾選食譜后,其成分顯示在列表中。HTML<ion-content>  <ion-grid>    <ion-row>      <ion-col>        <ion-list>          <ion-item            *ngFor="let recipe of loadedRecipes; let lastRecipe = last"            [ngClass]="{ 'last-recipe': lastRecipe }"          >            <ion-checkbox              (ionChange)="onCheckRecipe($event)"              value="{{recipe.name}}"            ></ion-checkbox>            <ion-label>{{recipe.name}}</ion-label>            <ion-button              [routerLink]="['/','recipes','recipe-details', recipe._id]"              >></ion-button            >          </ion-item>        </ion-list>      </ion-col>    </ion-row>    <ion-row>      <ion-col>        <h6 class="ion-padding-start" *ngIf="groceryList.length > 0">          Grocery List        </h6>        <ion-list *ngIf="groceryList.length > 0">          <ion-item *ngFor="let ingredient of groceryList">            <ion-label>{{ingredient.name}}</ion-label>            <ion-note slot="end">{{ingredient.quantity}} g</ion-note>          </ion-item>        </ion-list>      </ion-col>    </ion-row>  </ion-grid></ion-content>
查看完整描述

2 回答

?
慕村9548890

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;

  }

}

根據你所說的,你想要做的是:

  1. 減去歸因于已刪除配方的數量

  2. 如果新數量為零,則從列表中刪除該成分(盡管您也可以保留它并忽略數量為零的成分)

試試這個:

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)

          }

        }

      }

  }

}



查看完整回答
反對 回復 2023-03-24
?
汪汪一只貓

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;

}

  1. if 語句應該檢查數量而不是再次驗證名稱和 id ,比如

    if(matched.quantity <= eachIngredient.quantity){ // 拼接項目并刪除它。} else { // 減少數量 }

  2. 找到匹配成分的小建議。先用findIndex()檢索matchedIndex,再用grocerylist[matchedIndex]檢索item,避免再次遍歷grocerylist尋找索引進行拼接。


查看完整回答
反對 回復 2023-03-24
  • 2 回答
  • 0 關注
  • 133 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號