1. 程式人生 > 實用技巧 >js陣列Array根據動態條件過濾

js陣列Array根據動態條件過濾

資料

[{
    "name": "張三",
    "score": 153
}, {
    "name": "李四",
    "score": 206
}, {
    "name": "王五",
    "score": 68.5
}, {
    "name": "王六",
    "score": 83.5
}]

需求:需要根據動態的條件來對資料進行查詢。

步驟1:定義過濾器並初始化,比如我們要查詢王五以6分開頭的資料,條件定義:`姓名 equal 王五 && 成績 beginWith 6`

/// 過濾器集合,格式:{field:'',relationType:'',value: ''}
/// field - 用於過濾的屬性(欄位) /// relationType - 關聯關係(比較方式),可選值有equal(等於)、notEqual(不等於)、like(模糊匹配)、beginWith(以它開頭)、endWith(以它結尾) /// value - 用於被比較的過濾器值 const filters = [] filters.push({ field: 'name', relationType: 'equal', value: '王五' }) filters.push({ field: 'score', relationType: 'beginWith', value:
'6' })

步驟2:定義一個通用的過濾函式,過濾函式傳遞2個引數,第1個是需要被過濾的資料來源,第2個是過濾器集合,函式返回值是過濾後的資料來源

// 過濾資料來源
function filteringDataSources (source, filters) {
  // 動態表示式集合,用於儲存判斷某個物件是否滿足條件的函式
  const expressions = []
  // 遍歷過濾器集合,動態新增表示式函式
  filters.forEach(item => {
    // 新增表示式函式,引數為陣列的每個資料物件
    expressions.push((obj) => {
      
// 是否符合條件 let isFit = false // 資料物件對應的屬性值 let objValue = '' // 用於被比較的過濾器值 const compareValue = item.value // 判斷資料物件是否存在用於過濾的屬性,如果不存在直接判定為不符合條件 if (typeof (obj[item.field]) === 'undefined') { isFit = false return isFit } // 獲取資料物件用於比較的屬性值,統一轉為字串型別,便於比較 objValue = String(obj[item.field]) // 判斷邏輯 if (item.relationType === 'equal') { // 等於 isFit = objValue === compareValue } else if (item.relationType === 'notEqual') { // 不等於 isFit = objValue !== compareValue } else if (item.relationType === 'like') { // 模糊匹配 isFit = objValue.includes(compareValue) } else if (item.relationType === 'beginWith') { // 以它開頭 isFit = objValue.startsWith(compareValue) } else if (item.relationType === 'endWith') { // 以它結尾 isFit = objValue.endsWith(compareValue) } // 返回當前表示式是否符合條件 return isFit }) }) // 遍歷資料來源 source = source.filter((item, index) => { // 是否符合條件 let isFit = true // 遍歷表示式集合,迴圈判斷每個用於過濾的表示式函式是否符合 for (let index = 0; index < expressions.length; index++) { // 獲取表示式函式 const expression = expressions[index] // 呼叫表示式函式,獲取結果 const result = expression(item) // 如果結果為false,則終止表示式集合的遍歷(即有一個條件不符合,則該條資料則被判定不滿足條件) if (!result) { isFit = false break } } // 返回當前資料物件是否符合條件,不符合條件則被過濾掉,不會出現在最終資料中 return isFit }) // 返回過濾後的資料來源 return source }

步驟3:呼叫過濾函式得到結果

if (filters.length > 0) {
  source = filteringDataSources(source, filters)
}

結果:

Array(1)
0: {name(test_scores): "王五", score(test_scores): 68.5}
length: 1

完整程式碼:

// 過濾資料來源
function filteringDataSources (source, filters) {
  // 動態表示式集合,用於儲存判斷某個物件是否滿足條件的函式
  const expressions = []
  // 遍歷過濾器集合,動態新增表示式函式
  filters.forEach(item => {
    // 新增表示式函式,引數為陣列的每個資料物件
    expressions.push((obj) => {
      // 是否符合條件
      let isFit = false
      // 資料物件對應的屬性值
      let objValue = ''
      // 用於被比較的過濾器值
      const compareValue = item.value
      // 判斷資料物件是否存在用於過濾的屬性,如果不存在直接判定為不符合條件
      if (typeof (obj[item.field]) === 'undefined') {
        isFit = false
        return isFit
      }

      // 獲取資料物件用於比較的屬性值,統一轉為字串型別,便於比較
      objValue = String(obj[item.field])

      // 判斷邏輯
      if (item.relationType === 'equal') { // 等於
        isFit = objValue === compareValue
      } else if (item.relationType === 'notEqual') { // 不等於
        isFit = objValue !== compareValue
      } else if (item.relationType === 'like') { // 模糊匹配
        isFit = objValue.includes(compareValue)
      } else if (item.relationType === 'beginWith') { // 以它開頭
        isFit = objValue.startsWith(compareValue)
      } else if (item.relationType === 'endWith') { // 以它結尾
        isFit = objValue.endsWith(compareValue)
      }

      // 返回當前表示式是否符合條件
      return isFit
    })
  })

  // 遍歷資料來源
  source = source.filter((item, index) => {
    // 是否符合條件
    let isFit = true
    // 遍歷表示式集合,迴圈判斷每個用於過濾的表示式函式是否符合
    for (let index = 0; index < expressions.length; index++) {
      // 獲取表示式函式
      const expression = expressions[index]
      // 呼叫表示式函式,獲取結果
      const result = expression(item)
      // 如果結果為false,則終止表示式集合的遍歷(即有一個條件不符合,則該條資料則被判定不滿足條件)
      if (!result) {
        isFit = false
        break
      }
    }

    // 返回當前資料物件是否符合條件,不符合條件則被過濾掉,不會出現在最終資料中
    return isFit
  })

  // 返回過濾後的資料來源
  return source
}

let source = [{
  'name': '張三',
  'score': 153
}, {
  'name': '李四',
  'score': 206
}, {
  'name': '王五',
  'score': 68.5
}, {
  'name': '王六',
  'score': 83.5
}]
/// 過濾器集合,格式:{field:'',relationType:'',value: ''}
///     field - 用於過濾的屬性(欄位)
///     relationType - 關聯關係(比較方式),可選值有equal(等於)、notEqual(不等於)、like(模糊匹配)、beginWith(以它開頭)、endWith(以它結尾)
///     value - 用於被比較的過濾器值
const filters = []
filters.push({
  field: 'name',
  relationType: 'equal',
  value: '王五'
})
filters.push({
  field: 'score',
  relationType: 'beginWith',
  value: '6'
})
source = filteringDataSources(source, filters)
console.log(source)