我有一个Inventory类,它有几个方法。 2方法返回他们拥有的所有狮子和狼。一种方法将狮子和狼的数组合并为一个数组。最后,我有一个方法,我想根据输入过滤掉某些对象。
class Inventory {
getAllLions(): ILion[] {
const lions = [
{ id: 1, name: 'Joffrey', gender: Gender.male, vertrabrates: true, warmBlood: true, hair: 'Golden', runningSpeed: 30, makeSound() { } },
{ id: 2, name: 'Tommen', gender: Gender.male, vertrabrates: true, warmBlood: true, hair: 'Golden', runningSpeed: 30, makeSound() { } },
{ id: 3, name: 'Marcella', gender: Gender.female, vertrabrates: true, warmBlood: true, hair: 'Golden', runningSpeed: 30, makeSound() { } },
];
return lions;
}
getAllWolves(): IWolf[] {
const wolves: IWolf[] = [
{ id: 1, name: 'Jon', gender: Gender.male, vertrabrates: true, warmBlood: true, hair: 'Grey', runningSpeed: 30, makeSound() { } },
{ id: 2, name: 'Robb', gender: Gender.male, vertrabrates: true, warmBlood: true, hair: 'Black', runningSpeed: 30, makeSound() { } },
{ id: 3, name: 'Sansa', gender: Gender.female, vertrabrates: true, warmBlood: true, hair: 'Grey', runningSpeed: 30, makeSound() { } },
{ id: 4, name: 'Arya', gender: Gender.female, vertrabrates: true, warmBlood: true, hair: 'White', runningSpeed: 30, makeSound() { } },
];
return wolves;
}
getAllAnimals(allLions: ILion[], allWolves: IWolf[]): IAnimal[] {
const allAnimals = allLions.concat(allWolves);
return allAnimals
};
static getAnimalBy(name: string, gender: Gender, hair: string, runningSpeed: number, allAnimals): any[] {
let found = false;
let results = [];
for (let animal of allAnimals) {
if (name === animal.name || gender === animal.gender || hair === animal.hair || runningSpeed === animal.runningSpeed) {
found = true;
results.push(animal);
}
}
if (found) { return results } else { alert('No results'); return [] }
}
}
在getAnimalBy
我有几个参数。这些是用户可以过滤动物的参数。目前它只适用于一个值。如果我这样做:
const filterdAnimal = Inventory.getAnimalBy(null, Gender.female, null, null, allAnimals);
我得到的所有结果都与女性性别相同。但如果我这样做:
const filterdAnimal = Inventory.getAnimalBy(null, Gender.female, 'Golden', null, allAnimals);
它将与Golden
相等的对象添加到结果中。
只显示与女性和黄金头发价值相等的结果会是一个好方法吗?
答案 0 :(得分:2)
您可以在谓词中使用JS“filter”数组函数:
var allAnimals: Array<Animal>;
var found = allAnimals.filter(animal => {
return name === animal.name || gender === animal.gender || hair === animal.hair || runningSpeed === animal.runningSpeed;
});
此外,我们可以使用模板对象进行过滤:
function findByTemplate(allAnimals: Array<Animal>, template: any) {
return allAnimals.filter(animal => {
return Object.keys(template).every(propertyName => animal[propertyName] === template[propertyName]);
});
}
用法:
var found = findByTemplate(allAnimals, {name: "Aw", gender: "Male"});
var found = findByTemplate(allAnimals, {name: "Aw"});
var found = findByTemplate(allAnimals, {name: "Aw", gender: "Male", hair: "Red", runningSpeed: 50});
广义解决方案:
function findByTemplate(objects: Array<any>, template: any) {
return objects.filter(obj => {
return Object.keys(template).every(propertyName => obj[propertyName] === template[propertyName]);
});
}
我们可以通过模板对象在任何类型的对象数组中找到它。
让我们传递一些对象的数组和{name:“Aw”,性别:“男性”}作为模板对象。
objects.filter遍历数组,如果谓词函数返回true,则包含过滤结果中的项。
谓词函数:
obj => {
return Object.keys(template).every(propertyName => obj[propertyName] === template[propertyName]);
}
从传递的模板中获取密钥
模板的'Object.keys(模板)'{name:“Aw”,性别:“男性”}'返回数组
["name", "gender"]
所以我们只检查传递的属性。 我们将检查'[“name”,“gender”]'数组中所有项目的条件(另一个内部谓词)是否为真:
propertyName => obj[propertyName] === template[propertyName]
其中propertyName将采用“name”和“gender”值。
然后propertyName =“name”它测试是否
obj.name === template.name
在propertyName =“gender”之后,它会测试是否
obj.gender === template.gender
如果传递了所有测试(名称和性别),我们将在第一个谓词中返回true并在过滤结果中获取相应的对象。
解释比代码大,希望它足够清楚......