• 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:动态条件过滤来自于工作中的一个需求

    过滤前:

    过滤后:

    嘴角上扬,记得微笑
  • 相关阅读:
    团队冲刺(二)个人工作总结6
    团队冲刺(二)个人工作总结4
    网页开发--03(wampserver安装服务无法启动的问题)
    网页开发--02(开发环境配置)
    网页开发--01(常识)
    Three.js学习笔记05
    Three.js学习笔记04--纹理
    Three.js学习笔记03--光
    Three.js学习笔记02
    Three.js学习笔记01
  • 原文地址:https://www.cnblogs.com/jardeng/p/13518067.html
Copyright © 2020-2023  润新知