![](/img/trans.png)
[英]Lodash or best approach to combining two arrays of objects with matching key
[英]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});
}
}
更新的答案:
在forEach中无法访问“ this.ingredients”,因为该函数调用的上下文已更改
因此,将“ 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.