javascript - 基于三个或更多输入的 Lodash 过滤器
问题描述
我试图构建一个基于三个输入选择器的过滤器。逻辑如下:
- 如果仅选择了三个输入中的一个,则过滤器应仅基于此选择器值而不是未选择的输入返回所有结果
- 如果选择了三个输入中的两个,则应仅基于这两个而不是未选择的输入来过滤结果
- 如果已选择所有三个输入,则应在所有三个上过滤结果
我的代码感觉冗长且不可扩展(见下文)。有人对如何优化这个有想法吗?
这就是我目前正在使用的。hasSelectedBuildingtype
,hasSelectedInstrument
并hasSelectedRegion
检查是否已选择输入。因此,我手动检查所有输入的状态:
<!-- language: lang-js -->
result = _.filter(this.examples, function(entry) {
// Single checks (if only bulding or region or instrument selected)
if (
hasSelectedBuildingtype &&
!hasSelectedRegion &&
!hasSelectedInstrument
) {
if (
entry.buildingtypes.includes(
vm.selectedBuildingtype
)
) {
return true;
}
}
if (
hasSelectedInstrument &&
!hasSelectedRegion &&
!hasSelectedBuildingtype
) {
if (entry.instruments.includes(vm.selectedInstrument)) {
return true;
}
}
if (
hasSelectedRegion &&
!hasSelectedInstrument &&
!hasSelectedBuildingtype
) {
if (entry.regionid === vm.selectedRegion) {
return true;
}
}
// Double checks (if only bulding AND region or instrument AND etc selected)
if (
hasSelectedRegion &&
hasSelectedBuildingtype &&
!hasSelectedInstrument
) {
if (
entry.regionid === vm.selectedRegion &&
entry.buildingtypes.includes(
vm.selectedBuildingtype
)
) {
return true;
}
}
if (
hasSelectedInstrument &&
hasSelectedBuildingtype &&
!hasSelectedRegion
) {
if (
entry.instruments.includes(vm.selectedInstrument) &&
entry.buildingtypes.includes(
vm.selectedBuildingtype
)
) {
return true;
}
}
if (
hasSelectedInstrument &&
hasSelectedRegion &&
!hasSelectedBuildingtype
) {
if (
entry.instruments.includes(vm.selectedInstrument) &&
entry.regionid === vm.selectedRegion
) {
return true;
}
}
// Triple check (if all types selected)
if (
hasSelectedInstrument &&
hasSelectedRegion &&
hasSelectedBuildingtype
) {
if (
entry.instruments.includes(vm.selectedInstrument) &&
entry.regionid === vm.selectedRegion &&
entry.buildingtypes.includes(
vm.selectedBuildingtype
)
) {
return true;
}
}
});
谢谢!
解决方案
您可以做的一件事是对每个布尔标志使用位别名。您需要一份合同,以一个整数说明每个标志的位置。所以假设
bit 0: hasSelectedBuildingtype
bit 1: hasSelectedRegion
bit 2: hasSelectedInstrument
...
那么您的初始任务将以这种方式完成;
let myInputFlags = hasSelectedBuildingtype << 0 |
hasSelectedRegion << 1 |
hasSelectedInstrument << 2 |
// ... << 3, << 4, etc
然后你的比较变得像比较一个整数一样简单,例如
/**
* Checking that hasSelectedBuildingtype === false
* and hasSelectedRegion === false
* and hasSelectedInstrument === true
*/
if (myInputFlags === 4) {
...
您可以进一步为比较数字创建别名,例如;
let hasSelected = {
...,
INSTRUMENT_ONLY: 4,
...
};
使您的分支变得更具表现力。例如
if (myInputFlags === hasSelected.INSTRUMENT_ONLY) {
...
这样,如果您想在将来添加额外的布尔检查,您只需要维护这些值并在公式中添加额外的按位 OR。
推荐阅读
- android - 在 EditText 上调用 setText() 时会发生什么?
- java - Spring boot 2:使用 Flyway 时检测到明显的连接泄漏
- jquery - 属性以选择器开头 = 属性以选择器开头?
- git - Git:--git-dir 将所有文件显示为丢失
- java - 使用 Angular 6 和 Spring Rest API 下载文件
- javascript - 在服务器端分页上防止来自 jquery 数据表的多个 ajax 调用
- python - Python/Pandas:读取嵌套的 JSON
- haskell - Haskell - 与数据类型匹配的模式
- mongodb - 删除内部字段数组 MongoDb 的元素
- c# - 工厂设计模式是否适用于这种情况