前言
说起过滤是非常常见的业务,一般过滤推荐是服务端处理,发送请求进行模糊查询 这种情况一下,服务端返回的是每条数据中的某一个字段符合条件的数据集合
如果是前端要处理这个情况呢,前端处理过滤如果只是对于某个字段符合其中的条件很好处理,就像服务端一样,但是如果是多个字段的条件都要满足来处理的话,那就只能实现一个通用的方法来处理了
代码
单条件过滤查询
表示页面用一个输入框来搜索列表中的所有会匹配的内容,没有指定字段
export const searchBlurIgnoreCase = (
str1: string,
str2: string
): boolean => {
return data.toLocaleLowerCase().indexOf(val.toLocaleLowerCase()) >= 0;
};
//统一过滤查询
export const filterDataBySearch = function (
sourceData: Array<any>, //原始过滤数组数据
keys: Array<string>, //需要进行过滤的字段的数组集合
target: string //用于过滤的值
) {
if (!target) return sourceData;
//使用源数据进行过滤 交给过滤
const result = sourceData.filter((data) => {
//通过存储每条数据每个要过滤的字段的情况,收集成布尔值数组
const flags: boolean[] = [];
keys.forEach((key) => {
if (!data[key]) {
//空数据判断
flags.push(false);
} else {
const res = searchBlurIgnoreCase(data[key], target);
flags.push(res);
}
});
return flags.includes(true);
});
return result; //交给filterData
};
多条件多字段过滤查询
需要满足多个字段的条件的过滤查询,同时筛选出满足这些条件的数据,在服务端给的数据列表中,也是当时列表没有使用分页器去写的一个算法实现,但是现在想想列表没有分页器是真的很离谱,所以现在过滤都是服务端处理的,现在看一下代码实现
export const searchBlurIgnoreCase = (
str1: string,
str2: string
): boolean => {
return data.toLocaleLowerCase().indexOf(val.toLocaleLowerCase()) >= 0;
};
/**
* 多字段过滤查询
* @param filterData 过滤目标数组
* @param sourceData 源数组
* @param filterManager 需要过滤的键管理对象,该对象用于存储过滤的键名和值
* @param filedMap 过滤键名对应过滤数组的字段名
*/
interface KeyBooleanArrayType {
[propsName: string]: boolean[];
}
export const multiFiledFilter = () => {
function handleDataFilter(
filterData: any[],
sourceData: any[],
filterManager: object,
filedMap: object
) {
const keys = Object.keys(filterManager);
//过滤掉没有值的键名
const res = keys.filter((key) => {
return filterManager[key] !== "";
});
if (!res.length) return clearDataFilter(filterData,sourceData,filterManager);
const flags: KeyBooleanArrayType[] = [];
res.forEach((key, i) => {
//数据到达最后一个时,返回结果
if (i === res.length - 1) {
//只有一个字段要查询
if (res.length === 1) {
filterData = sourceData.filter((item) => {
return item[filedMap[key]] && searchBlurIgnoreCase(
item[filedMap[key]],
filterManager[key]
);
});
} else {
//到最后一个索引时进行过滤整合处理
filterData = sourceData.filter((item, j) => {
return (
item[filedMap[key]] && searchBlurIgnoreCase(item[filedMap[key]], filterManager[key]) &&
getArrayIndexSameLevelVal(flags, j)
);
});
}
return;
}
//源数据进行遍历
sourceData.forEach((item, i) => {
//处理当前过滤的结果返回布尔值
const res = item[filedMap[key]] && searchBlurIgnoreCase(
item[filedMap[key]],
filterManager[key]
);
//建立以属性名为key,以布尔数组为值
if (i === 0) {
flags.push({
[key]: [res],
});
} else {
flags.forEach((flagObj) => {
if (flagObj[key]) {
flagObj[key].push(res);
}
});
}
});
});
return filterData
}
function getArrayIndexSameLevelVal(
arr: KeyBooleanArrayType[],
index: number
) {
const res: boolean[] = [];
const keys: string[] = arr.map((flagObj) => Object.keys(flagObj)[0]);
arr.forEach((flagObj, i) => {
const key = keys[i]!;
flagObj[key].forEach((b, j) => {
if (j === index) {
res.push(b);
}
});
});
return res.every((item) => item);
}
function clearDataFilter(
filterData: any[],
sourceData: any[],
filterManager: object
) {
for (const key in filterManager) {
if (Object.prototype.hasOwnProperty.call(filterManager, key)) {
filterManager[key] = "";
}
}
filterData = [...sourceData];
return filterData
}
return {
handleDataFilter,
clearDataFilter,
};
};