javascript - 根据多个值过滤数组

标签 javascript typescript

我有一个包含多个方法的 Inventory 类。 2 方法返回他们拥有的所有狮子和狼。一种方法将 lions 和 wolves 的数组合并为一个数组。最后,我有一个方法可以用来根据输入过滤掉某些对象。

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 的对象添加到结果中。

如果只显示女性性别和金发值相等的结果,有什么好的方法吗?

最佳答案

您可以将 JS“过滤器”数组函数与谓词一起使用:

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", gender: "Male"} 作为模板对象。

objects.filter 遍历数组并在谓词函数返回 true 时将项目包含在过滤结果中。

谓词函数:

obj => {
    return Object.keys(template).every(propertyName => obj[propertyName] === template[propertyName]);
}

从传递的模板中获取 key

Object.keys(template) for template '{name: "Aw", gender: "Male"}' 返回数组

["name", "gender"]

所以我们将只检查传递的属性。 我们将检查我们的条件(另一个内部谓词)是否对 '["name", "gender"]' 数组中的所有项目都为真:

propertyName => obj[propertyName] === template[propertyName]

其中 propertyName 将采用“姓名”和“性别”值。

然后propertyName = "name"测试是否

obj.name === template.name

在那之后 propertyName = "gender"并测试是否

obj.gender === template.gender

如果所有测试(姓名和性别)都通过,我们将在第一个谓词中返回 true 并在筛选结果中获取相应的对象。

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

关于javascript - 根据多个值过滤数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37159443/

相关文章:

javascript - 在 HTML Canvas 上移动元素

javascript - 处理两个ajax请求中只有一个成功执行的情况

javascript - 处理动态创建的 <select> 下拉选项上的事件

typescript - 使用 jsPDF rtl 支持的 Html 到 pdf

javascript - 最小化源代码文件后,JavaScript 源映射文件是否仍然有效?

javascript - 在 JavaScript 上将属性从字符串更新为对象而不发生突变

typescript - 使用 Typescript 导入时,TFJS 抛出 TS2411 作为错误

javascript - 为什么 substring 方法会以这种方式运行?

javascript - 自动完成搜索框并将值传递给 flask

typescript - 将 useState 输出的 typescript 设置为对象数组的元素之一