JS实现数组过滤从简单到多条件筛选
⽬录
单条件单数据筛选
单条件多数据筛选
多条件单数据筛选
多条件多数据筛选
知识点1: Object.key() 获取数组索引或者对象属性
知识点2: js⾥的falsy
知识点3: Array.every 与 Array.some的区别
知识点4: 数组的深拷贝与浅拷贝
想⼀想:递归算法的优化
在上家公司⼯作的时候,有⼀个需求是在前端部分完成筛选功能,⼀次拿到所有数据,然后根据条件筛选。通常情况下筛选是后台给接⼝,在数据量不⼤的情况下,也有⼈可能会遇到前端筛选这样的情况,特别写了这篇⽂章分享给⼤家,有问题请指出,互相学习。
⼀般情况下的单条件筛选,数组的filter⽅法就能够满⾜需求,本⽂讨论的重点是多条件下的复合筛选,并列出了⼏个相关知识点。
以下是很多个
// 这个是例⼦中的被筛选数组
var aim = [
{name:'Anne', age: 23, gender:'female'},
{name:'Leila', age: 16, gender:'female'},
{name:'Jay', age: 19, gender:'male'},
{name:'Mark', age: 40, gender:'male'}
]
单条件单数据筛选
根据单个名字筛选,⽤filter⽅法,判断name是否为⽬标名字即可
// 根据单个名字筛选
function filterByName(aim, name) {
return aim.filter(item => item.name == name)
}
// 输⼊ aim 'Leila' 期望输出为 [{name:'Leila', age: 16, gender:'female'}]
console.log(filterByName(aim,'leila'))
单条件多数据筛选
根据多个名字筛选,这⾥是⽤for循环遍历⽬标数组,然后⽤find⽅法到后push到结果数组⾥,⽤find⽅法是重名情况下也能得到想要的结果。for循环可以⽤数组的⼀些遍历⽅法替代,代码可以更简化,⽰例就是⼤概表达个意思。
// 根据多个名字筛选
function filterByName1(aim, nameArr) {
let result = []
for(let i = 0; i < nameArr.length; i++) {
result.push(aim.find(item => item.name = nameArr[i]))
}
return result
}
// 输⼊ aim ['Anne','Jay']
//期望输出为 [{name:'Anne', age: 23, gender:'female'},{name:'Jay', age: 19, gender:'male'}]
console.log(filterByName1(aim,['Leila','Jay']))
/
/ 有BUG 改进后
多条件单数据筛选
根据单个名字或者单个年龄筛选,⽤filter⽅法,判断条件之间是或的关系。
// 根据名字或者年龄筛选
function filterByName2(aim, name, age) {
return aim.filter(item => item.name == name || item.age == age)
}
console.log(filterByName2(aim,'Leila',19))
多条件多数据筛选
我最初是⽤了很笨的双for循环去做,发现很慢,⽽且并没有达到预期的效果。具体的⼼路历程已经太遥远,简单介绍以下这个筛选算法。
⾸先是把筛选条件都塞到⼀个对象⾥,⽤object对象的keys⽅法获取到筛选的条件名,及需要筛选的是哪个条件,是name?age? gender?
然后使⽤filter⽅法对⽬标数据进⾏筛选, 如下⬇
根据名字和年龄多元素筛选
//根据名字和年龄多元素筛选
export function multiFilter(array, filters) {
const filterKeys = Object.keys(filters)
// filters all elements passing the criteria
return array.filter((item) => {
// dynamically validate all filter criteria
return filterKeys.every(key => {
//ignore when the filter is empty Anne
if(!filters[key].length) return true
return !!~filters[key].indexOf(item[key])
})
})
}
/*
* 这段代码并⾮我原创,感兴趣的可以去原作者那⾥点个赞
* 作者是:@author gist.github/jherax
* 这段代码⾥我只加了⼀⾏,解决部分筛选条件清空时候整体筛选失效的问题
*/
var filters = {
name:['Leila', 'Jay'],
age:[]
}
/* 结果:
* [{name: "Leila", age: 16, gender: "female"},
* {name: "Jay", age: 19, gender: "male"}]
*/
例如这⾥,判断每条数据的name值是否在filters.name数组⾥,是的话返回true,判断filters.age是空数组的话直接返回true,空数组是模拟了age条件被清空的情况,我们仍然能得到正确的筛选数据。
知识点1: Object.key() 获取数组索引或者对象属性
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr));
// ["0", "1", "2"]
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj));
// ["0", "1", "2"]
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj));
// ["2", "7", "100"] 猜猜为啥?
知识点2: js⾥的falsy
falsy : 0 , false, "", null, undefined, NaN
在判断语句中,只有上⾯6种情况会是false,其余的都是true
var a;
if(a!=null&&typeof(a)!=undefined&&a!=''){
//a有内容才执⾏的代码
}
if(!!a){jsarray删除元素
//a有内容才执⾏的代码...
}
知识点3: Array.every 与 Array.some的区别
我的理解是在遍历数组的时候:
Array.every的条件是「与」的关系,全真为真,及条件全为true则为true,有⼀个false就返回false
Array.some的条件是「或」的关系,有真为真,条件有⼀个true就返回true,条件全为false的时候才返回false
下⾯举个
// 判断每个名字都为Anne?
let dataEvery = aim.every(item => item.name === 'Anne') // false
let dataEvery = aim.some(item => item.name === 'Anne') // true
// 判断每个名字都是字符串?
let dataEvery = aim.every(item => typeof item.name === 'string') // true
let dataEvery = aim.some(item => typeof item.name === 'string') // true
知识点4: 数组的深拷贝与浅拷贝
最近参与⼀些前端的⾯试⼯作,深拷贝与浅拷贝是我最爱问的问题之⼀。⼀个问题就考察了数据类型,数组操作,递归算法等。
因为数组是js⾥的引⽤类型,单纯复制时复制的是其引⽤关系。在对获取的数据进⾏筛选时,我并不希望影响原始数据,所以我要⽤到「深拷贝」得到与原始数据数据结构完全相同⼜相互独⽴的数据,⽽不是只复制其引⽤关系。
/
/ 我常⽤⽅法,如果项⽬很⼤,不推荐
let obj1 = JSON.parse(JSON.stringify(obj))
// deepclone
function deepClone(o1, o2) {
for (let k in o2) {
if (typeof o2[k] === 'object') {
o1[k] = {};
deepClone(o1[k], o2[k]);
} else {
o1[k] = o2[k];
}
}
}
想⼀想:递归算法的优化
这个知识点与本⽂关系不⼤。 抱歉之前的误导。
这个是看掘⾦⼩册前端⾯试指南看到的,讲算法的时候提了⼀下递归算法的优化,初见的时候⼜被惊艳到,还没有在项⽬⾥⽤到。感兴趣的可以试试,这个是斐波那契数列和。可以⾃⼰在浏览器⾥敲⼀下,试试不⽤缓存与⽤缓存的运算次数差别。
let count = 0;
function fn(n) {
let cache = {};
function _fn(n) {
if (cache[n]) {
return cache[n];
}
count++;
if (n == 1 || n == 2) {
return 1;
}
let prev = _fn(n - 1);
cache[n - 1] = prev;
let next = _fn(n - 2);
cache[n - 2] = next;
return prev + next;
}
return _fn(n);
}
let count2 = 0;
function fn2(n) {
count2++;
if (n == 1 || n == 2) {
return 1;
}
return fn2(n - 1) + fn2(n - 2);
}
到此这篇关于JS实现数组过滤从简单到多条件筛选的⽂章就介绍到这了,更多相关JS 数组过滤内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论