首页 > 解决方案 > 基于三个或更多输入的 Lodash 过滤器

问题描述

我试图构建一个基于三个输入选择器的过滤器。逻辑如下:

我的代码感觉冗长且不可扩展(见下文)。有人对如何优化这个有想法吗?

这就是我目前正在使用的。hasSelectedBuildingtypehasSelectedInstrumenthasSelectedRegion检查是否已选择输入。因此,我手动检查所有输入的状态:

<!-- 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;
        }
    }
});

谢谢!

标签: javascriptlodash

解决方案


您可以做的一件事是对每个布尔标志使用位别名。您需要一份合同,以一个整数说明每个标志的位置。所以假设

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。


推荐阅读