簡體   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