过滤多个值的数组

时间:2016-05-11 10:10:17

标签: javascript typescript

我有一个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相等的对象添加到结果中。

只显示与女性和黄金头发价值相等的结果会是一个好方法吗?

1 个答案:

答案 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});

更新1

广义解决方案:

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并在过滤结果中获取相应的对象。

解释比代码大,希望它足够清楚......