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)

 

PS:動態條件過濾來自於工作中的一個需求

過濾前:

過濾后:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM