【问题标题】:Elegant way to do multiple parameter filter for client-side search为客户端搜索进行多参数过滤的优雅方式
【发布时间】:2020-01-24 08:07:34
【问题描述】:

所以,假设我有一个如下所示的对象:

const DEVICES: { mac: string; name: string; ip: string; type: number }[] = [
  {
    mac: 'xx:xx:xx:xx:xx',
    name: 'something',
    ip: 'xx.xx.xx.xx.xx',
    type: 0,
  },
  {
    mac: 'xx:xx:xx:xx:yy',
    name: 'something1',
    ip: 'xx.xx.xx.xx.yy',
    type: 1,
  },
  // and so on...
];

当我想要有多个可搜索参数(名称、mac、ip)时 - 我的直觉是将一些 ||(OR)放入我的过滤器函数中,例如:

 DEVICES.filter((item) => {
   return item.name.toLowerCase().indexOf(dataFromInputEvent.trim().toLowerCase()) >= 0
          || item.ip.toLowerCase().indexOf(dataFromInputEvent.trim().toLowerCase()) >= 0
          || item.mac.toLowerCase().indexOf(dataFromInputEvent.trim().toLowerCase()) >= 0;
 })
 .map(item, index) = {
   return (
     <SomeComponent
       key={index}
       type={item.type}
       name={item.name}
       mac={item.mac}
       type={item.type}
     />
   );
 )}

如您所见,如果数据获得更多属性并且我要添加另一个参数进行搜索,我只需在过滤器函数中添加另一个|| 即可返回。有没有更优雅的方法来进行多参数搜索——最好不要重复相同的toLowerCase()indexOf()?或者可能完全不做|| 的事情?

【问题讨论】:

    标签: javascript reactjs typescript ecmascript-6


    【解决方案1】:

    创建一个要过滤的属性数组(当前为['name', 'ip', 'mac']),然后遍历它们并查看其中的.some 在使用item 上的括号表示法访问时是否包含数据:

    DEVICES.filter((item) => {
      const input = dataFromInputEvent.trim().toLowerCase();
      return ['name', 'ip', 'mac'].some(prop => item[prop].toLowerCase().includes(input));
    })
    .map( // ...
    

    (请注意,您可以先将修剪后的小写输入存储在一个变量中,然后使用.includes 而不是indexOf,从而减少代码的重复性)

    您可能还打算将 DEVICES 键入为对象数组,而不是单个对象:

    const DEVICES: Array<{ mac: string; name: string; ip: string; type: number }> = [
    

    但是 Typescript 几乎可以推断类型,而无需您显式记录它们,所以

    const DEVICES = [
    

    一个人可能就足够了。 (编写更少的代码意味着更少的错误表面积,并且通常也使事情更具可读性)

    【讨论】:

    • 所以说我已经用一个数组输入了 DEVICES 并创建了一个可搜索属性的数组,如何输入 .filter.some 函数的参数? :)
    • 啊,item[prop] 无法编译。由于您确定它始终是一个字符串,您可以使用(item[prop] as string)。另一种选择是将prop 数组声明为const,以便将其值解释为静态而不是泛化:(['name', 'ip', 'mac'] as const).some。我认为这就是您需要做的所有事情 - 只需选择其中之一即可。
    • (item[prop] as string) 由于某种原因无法正常工作。我不确定做这样的硬编码字符串数组是否好。我觉得维护起来会很累。也许我会在 const searchableProperties = ['name', 'ip']; 之类的地方声明它,然后调用变量?
    • 哎呀,我玩的时候和你的类型不同。是的,这种方法行不通,所以你必须使用另一种方法,as const
    • as const 表示法只是向类型检查器指示它应该完全按原样解释前面的表达式,而不是试图概括。没有它,属性名称数组将输入为string[] - 有了它,属性名称数组将输入为['name', 'ip', 'mac'],允许稍后将item[prop] 正确推断为string 类型。
    猜你喜欢
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    相关资源
    最近更新 更多