繁体   English   中英

角度检查两个数组中的匹配对象,TypeScript的最佳方法

[英]Angular check matching objects in two arrays, TypeScript best way

我遇到了问题,无法在TypeScript中解决。 我正在使用Angular,此代码来自服务。 我有以下各种成分:

private ingredients: Ingredient[] = [
  new Ingredient('farina', 500),
  new Ingredient('burro', 80),
  new Ingredient('uccellini', 5)
];

这是模型: export class Ingredient {constructor(public name: string, public amount: number){}}

现在,我想向数组添加新成分,并发出带有新数组副本的事件:可行:

newIngredients = [
  new Ingredient('mais', 100),
  new Ingredient('uccellini', 5)
];

addIngredients(newIngredients: Ingredient[]) {
  this.ingredients.push(...ingredients);
  this.ingredientsChanged.emit(this.ingredients.slice());
}

但我想检查是否在配料数组中存在新的配料对象,如果存在,则将单个对象中的旧值和新值相加,然后推送更新的对象,然后返回该数组的副本。

预期产量:

[
  new Ingredient('farina', 500),
  new Ingredient('burro', 80),
  new Ingredient('uccellini', 10)
  new Ingredient('mais', 100)
];

我尝试使用Set,WeakSet,Map和其他方式,但是我不太了解Typescript。 这就是我遇到的问题:

addIngredients(newIngredients: Ingredient[]) {

  let hash = {};
  this.ingredients.forEach(function (ingr) {
    hash[ingr.name] = ingr;
  });

let result = newIngredients.filter(function (ingr) {
  if (!(ingr.name in hash)) {
    return !(ingr.name in hash);
  } else {
    // ???
  }
});

  this.ingredients.push(...result);
  this.ingredientsChanged.emit(this.ingredients.slice());
}

感谢帮助

假设您有两个数组

const ingredients: Ingredient[] = [
  new Ingredient('farina', 500),
  new Ingredient('burro', 80),
  new Ingredient('uccellini', 5)
];

const newIngredients = [
  new Ingredient('mais', 100),
  new Ingredient('uccellini', 5)
];

如果要添加不存在的成分并合并存在的成分,则要合并它们,

您可以做的是合并两个数组,然后减少直到只有一个列表

const combined = ingredients
  .concat(newIngredients)
  .reduce((prev: any[], curr: any) => {
    const temp = prev.filter(a => a.name === curr.name)
    if (temp.length > 0) {
      prev.push({ ...curr, value: temp.shift().value + curr.value })
    } else {
      prev.push(curr)
    }
    return prev
  }, [])

以下是代码片段:

Stackblitz网址: https ://stackblitz.com/edit/angular-uf4dcr

app.component.html

<button (click)="add()">Add</button>

<ul>
  <li *ngFor="let ing of ingredients">
    {{ing.name}} - {{ing.amount}}
  </li>
</ul>

app.component.ts

import { Component } from '@angular/core';

class Ingredient {
  constructor(public name: string, public amount: number){ }
}



@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular 5';

  private ingredients: Ingredient[] = [
    new Ingredient('farina', 500),
    new Ingredient('burro', 80),
    new Ingredient('uccellini', 5)
  ];

  addIngredients(newIngredients: Ingredient) {

    let exist: boolean = false;
    this.ingredients.forEach(function (ingr) {
      if(ingr["name"] == newIngredients["name"]) {
        ingr["amount"] += newIngredients["amount"];
        exist = true;
      }
    });

    if(!exist) {
      this.ingredients.push(newIngredients);
    }

      //this.ingredientsChanged.emit(this.ingredients.slice());
      console.log([...this.ingredients]); //return copy of the updated array
  }

  add() {
    this.addIngredients({name: 'farina', amount:10});
    this.addIngredients({name: 'new item', amount:100});
  }

}

更新的答案:

  1. 在forEach中无法访问“ this.ingredients”,因为该函数调用的上下文已更改

  2. 因此,将“ this”分配给“ that”变量,从而可以在forEach内部访问“ that.ingredients”

StackBlitz网址: https ://stackblitz.com/edit/angular-fulrcg

addIngredients(newIngredients: Ingredient[]) {

    let exist: boolean = false;
    let that = this;
    //debugger;
    console.log(this.ingredients);
    newIngredients.forEach(function(newIngr, newKey) {
      exist = false;
      console.log(newIngr);
      that.ingredients.forEach(function (ingr, key) {
        if(ingr["name"] == newIngr["name"]) {
          ingr["amount"] += newIngr["amount"];
          exist = true;
        }
      });
      if(!exist) {
        **that.ingredients**.push(newIngr);
      }
    });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM