el-table 前端多条件查询

el-table 前端多条件查询(包括范围选择、和数组选择等)

问题描述

根据条件,在数组对象中筛选出来相关数据

// 条件
const condition = {
  age: {
   max: 22,
   min: 16
  },
  companyAge: {
   max: 4,
   min: 6
  },
  higDegree:['初中','高中'],
  positionKind: ['销售'],
  staffRank:['D2','其他'],
  name: '小明'
}
// 数据源
const dataSource = [
  {
    age: 18,
    companyAge: 7,
    higDegree: '初中',
    positionKind: '销售',
    staffRank: 'D2',
    name: '小明'
  },
  {
    age: 18,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '销售',
    staffRank: 'D2',
    name: '小张'
  },
  {
    age: 20,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '其他',
    staffRank: 'D2',
    name: '小亮'
  },
  {
    age: 19,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '其他',
    staffRank: 'D2',
    name: '小红'
  },
  {
    age: 19,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '销售',
    staffRank: 'D2',
    name: '小东'
  },
  {
    age: 23,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '销售',
    staffRank: '其他',
    name: '小光'
  },
]

你期待的结果是什么?

1.同时满足condition条件的才能被筛选出来
2.区间选择的:代表数据源的某个属性在这个区间内,
多选择的:代表数据源的属性值能匹配上任一项
3.比如:

条件是condition = {
  age: {
   max: 20,
   min: 18
  },
  companyAge: {
   max: 5,
   min: 4
  },
  higDegree:['初中','高中'],
  positionKind: ['销售'],
  staffRank:['D2','其他'],
  name: ''
}

能匹配上的数据源有:
[
  {
    age: 19,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '销售',
    staffRank: 'D2',
    name: '小东'
  }
]
阅读 3.9k
5 个回答
// 数据源
const dataSource = [
    {
        age: 18,
        companyAge: 7,
        higDegree: '初中',
        positionKind: '销售',
        staffRank: 'D2',
        name: '小明'
    },
    {
        age: 18,
        companyAge: 4,
        higDegree: '高中',
        positionKind: '销售',
        staffRank: 'D2',
        name: '小张'
    },
    {
        age: 20,
        companyAge: 4,
        higDegree: '高中',
        positionKind: '其他',
        staffRank: 'D2',
        name: '小亮'
    },
    {
        age: 19,
        companyAge: 4,
        higDegree: '高中',
        positionKind: '其他',
        staffRank: 'D2',
        name: '小红'
    },
    {
        age: 19,
        companyAge: 4,
        higDegree: '高中',
        positionKind: '销售',
        staffRank: 'D2',
        name: '小东'
    },
    {
        age: 23,
        companyAge: 4,
        higDegree: '高中',
        positionKind: '销售',
        staffRank: '其他',
        name: '小光'
    },
]
const filter = (arr, condition) => {
    let result = arr;
    Object.keys(condition).forEach(key => {
        let conditionValue = condition[key]
        if (Array.isArray(conditionValue) && conditionValue.length) {
            result = result.filter(item => conditionValue.includes(item[key]))
        } else if (typeof conditionValue === 'object') {
            result = result.filter(item => item[key] >= conditionValue.min && item[key] <= conditionValue.max)
        } else if (typeof conditionValue === 'string' && conditionValue) {
            result = result.filter(item => item[key] === conditionValue)
        }
    })
    return result;
}
console.log(filter(dataSource, {
    age: {
        max: 20,
        min: 18
    },
    companyAge: {
        max: 5,
        min: 4
    },
    higDegree: ['初中', '高中'],
    positionKind: ['销售'],
    staffRank: ['D2', '其他'],
    name: ''
}))

输出:

[
  {
    age: 18,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '销售',
    staffRank: 'D2',
    name: '小张'
  },
  {
    age: 19,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '销售',
    staffRank: 'D2',
    name: '小东'
  }
]
function fil2(obj1,obj2){
           var flag =true
           Object.keys(obj2).forEach(key => {
               let val = obj2[key]
               if (Array.isArray(val) && val.length) {
                   if(val.indexOf(obj1[key])==-1){
                       flag= false
                   }
               } else if (typeof val === 'object') {
                   if(obj1[key]>=val.min&&obj1[key]<=val.max){
                   }else{
                        flag= false
                   }
               } else if (typeof val === 'string' && val) {
                   if(obj1[key]!=val){
                       flag= false
                   }
               }
           })
           return flag
       }
       function fil(arr,obj){
           var item=[]
           for(var i=0;i<arr.length;i++){
               if(fil2(arr[i],obj)){
                   item.push(arr[i])
               }
           }
           return item
       }
       console.log(fil(dataSource, {
           age: {
               max: 20,
               min: 18
           },
           companyAge: {
               max: 5,
               min: 4
           },
           higDegree: ['初中', '高中'],
           positionKind: ['销售'],
           staffRank: ['D2', '其他'],
           name: ''
       }))
    const filterFun = (item, { key, val }) => {
      if (!val) return true;
      if (Array.isArray(val)) {
        return val.includes(item[key]);
      }
      if (typeof val === "string") {
        return val === item[key];
      }
      if (typeof val === "object") {
        return item[key] <= val.max && item[key] >= val.min;
      }
    };
    const result = dataSource.filter(item => {
      const arrs = [];
      for (let k in condition) {
        arrs.push(filterFun(item, { key: k, val: condition[k] }));
      }
      return arrs.every(r => r);
    });
    console.log(result);

function filterBy(list, conditions) {
    const filterMaps = [
        [
            (_, opt) => typeof opt === "string" &&  !!opt,
            (name, opt) => it => it[name] === opt,
        ],
        [
            (_, opt) => Array.isArray(opt),
            (name, opt) => it => opt.includes(it[name]),
        ],
        [
            (_, opt) => typeof opt === "object" && "min" in opt && "max" in opt,
            (name, opt) => it => it[name] >= opt.min && it[name] <= opt.max,
        ]
    ];

    const checkers = Object.entries(conditions)
        .map(([key, value]) => {
            const [, create] = filterMaps.find(([test]) => test(key, value)) ?? [];
            return create?.(key, value);
        })
        .filter(c => c);

    const it = list[0];
    checkers.every(c => {
        console.log(c.toString(), c(it));
        return true;
    });

    return list.filter(it => checkers.every(c => c(it)));
}

console.log(filterBy(dataSource, condition));

筛选出来有 2 条是符合条件的

[
  {
    age: 18,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '销售',
    staffRank: 'D2',
    name: '小张'
  },
  {
    age: 19,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '销售',
    staffRank: 'D2',
    name: '小东'
  }
]

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。
function filterData(data, condition) {
  return data.filter(e => Object.entries(e).every(([k,v]) => {
    const cond = condition[k];
    return Array.isArray(cond) ? cond.includes(v) : typeof cond == 'string' ? cond === v : cond.min <= v && cond.max >= v;
  }));
}
// 条件
var condition = {
  age: {
   max: 20,
   min: 18
  },
  companyAge: {
   max: 5,
   min: 4
  },
  higDegree:['初中','高中'],
  positionKind: ['销售'],
  staffRank:['D2','其他'],
  name: '小东'
}
// 数据源
var dataSource = [
  {
    age: 18,
    companyAge: 7,
    higDegree: '初中',
    positionKind: '销售',
    staffRank: 'D2',
    name: '小明'
  },
  {
    age: 18,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '销售',
    staffRank: 'D2',
    name: '小张'
  },
  {
    age: 20,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '其他',
    staffRank: 'D2',
    name: '小亮'
  },
  {
    age: 19,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '其他',
    staffRank: 'D2',
    name: '小红'
  },
  {
    age: 19,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '销售',
    staffRank: 'D2',
    name: '小东'
  },
  {
    age: 23,
    companyAge: 4,
    higDegree: '高中',
    positionKind: '销售',
    staffRank: '其他',
    name: '小光'
  },
]

// 看例子里name是空字符但匹配了name为小东,不是很确定单值是否要参与条件匹配
// 如果需要则改下函数内的关于string类型的匹配规则即可
// 另外就是是否会有字段没有的情况,需要的话这种情况判断也要加进去
filterData(dataSource, condition)
已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题