繁体   English   中英

有没有更好的方法在 JavaScript 中编写冗余过滤器语句?

[英]Is there a better way to write redundant filter statements in JavaScript?

我有多个 if 语句,我使用三元运算符呈现,然后为每个 If 一个单独的过滤器,这在 React 中工作得很好,但是过滤器语句的重复使代码看起来不整洁,有没有办法消除这种重复?

let ar = data;
id === 'A' ? ar = ar.filter(item => item > 4) : Id === 'B' ? ar = ar.filter(item => item > 4 
&& item < 8) : Id === 'C' ? ar = ar.filter(item => item >8 && item < 15) : ar = data;

您可以创建一个 function,它将返回过滤器 function,例如:

function makeFilterFn(id){
  switch (id){
      case 'A':
        return item => item > 4
      case 'B':
        return item => item > 4 && item < 8
      case 'C':
        return item => item > 8 && item < 15
      default:
        return null
  }
}

const filterFn = makeFilterFn(id)

const result = filterFn ? ar.filter(filterFn) : ar

 const ar = [1,2,3,4,5,6,7,8,9,10]; const id = "A"; const filtered = { "A": ar.filter(item => item > 4), "B": ar.filter(item => item > 4 && item < 8), "C": ar.filter(item => item >8 && item < 15) }[id] console.log(filtered)

让我们进行一些重构,看看我们可以改进什么。 首先,我将它分成多行,以便我可以更容易地看到它:

let ar = data;
id === 'A' ?
  ar = ar.filter(item => item > 4) : 
id === 'B' ? 
  ar = ar.filter(item => item > 4 && item < 8) : 
id === 'C' ? 
  ar = ar.filter(item => item > 8 && item < 15) :
//default
ar = data;

我注意到的第一件事是您分配了多次,但使用了三元组,这使得它不需要。 让我们解决这个问题:

let ar = data
ar = (
id === 'A' ?
  ar.filter(item => item > 4) : 
id === 'B' ? 
  ar.filter(item => item > 4 && item < 8) : 
id === 'C' ? 
  ar.filter(item => item > 8 && item < 15) :
//default
data
)

接下来,每次都会调用ar.filter (默认情况除外),并且只有 arguments 发生变化。 可以将默认情况更改为返回所有内容的过滤器,使其更加一致,然后我们可以将 arguments 提取到变量中(我们称之为filter ):

let ar = data
// we are just determining the argument here
let filter = ( 
id === 'A' ?
  item => item > 4 : 
id === 'B' ? 
  item => item > 4 && item < 8 : 
id === 'C' ? 
  item => item > 8 && item < 15 :
// default is to return all items
item => true
)

// now we can use the argument in the function call
ar = ar.filter(filter)

这消除了这里的大部分重复,但我们多次以相同的方式与id进行比较。 就像Pavlos提到的,如果您想根据字符串 id 选择一个选项,基本对象可以让您这样做。 问题是我们失去了默认参数,但我们通常可以使用|| ("or") 运算符来解决这个问题:

let ar = data

// another benefit of doing it this way is that it is super easy to add 
// new filters now, and you can even pass this in as a prop to your component.
let filters = { 
  'A' : item => item > 4, 
  'B' : item => item > 4 && item < 8,
  'C' : item => item >8 && item < 15
}
let defaultFilter = item => true 

// pick the right filter
let filter = filters[id] || defaultFilter

// now filter the collection with that filter
ar = ar.filter(filter)

有了这个,您已经将选择正确过滤器的命令式过程转变为声明性过程。 filters object 现在列出没有任何逻辑的过滤器。 这更加灵活,并允许在代码库的其他部分进行更多的重构。

另一个可能有用的提示是重新排列参数,使item位于中间,数字 go 从最小到最大:

item => 4 < item && item < 8

(有关更多信息,请参阅此答案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM