JS中的数组过滤,从简单筛选到多条件筛选
栏目: JavaScript · 发布时间: 6年前
内容简介:在上家公司工作的时候,有一个需求是在前端部分完成筛选功能,一次拿到所有数据,然后根据条件筛选。通常情况下筛选是后台给接口,在数据量不大的情况下,也有人可能会遇到前端筛选这样的情况,特别写了这篇文章分享给大家,有问题请指出,互相学习。一般情况下的单条件筛选,数组的filter方法就能够满足需求,本文讨论的重点是多条件下的复合筛选,并列出了几个相关知识点。以下是很多个:chestnut::chestnut::chestnut::chestnut:
在上家公司工作的时候,有一个需求是在前端部分完成筛选功能,一次拿到所有数据,然后根据条件筛选。通常情况下筛选是后台给接口,在数据量不大的情况下,也有人可能会遇到前端筛选这样的情况,特别写了这篇文章分享给大家,有问题请指出,互相学习。
一般情况下的单条件筛选,数组的filter方法就能够满足需求,本文讨论的重点是多条件下的复合筛选,并列出了几个相关知识点。
以下是很多个:chestnut::chestnut::chestnut::chestnut:
// 这个是例子中的被筛选数组 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方法对目标数据进行筛选,:chestnut:如下:arrow_down:
根据名字和年龄多元素筛选
//根据名字和年龄多元素筛选 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 https://gist.github.com/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){ //a有内容才执行的代码... } 复制代码
知识点3: Array.every 与 Array.some的区别
我的理解是在遍历数组的时候:
Array.every的条件是「与」的关系,全真为真,及条件全为true则为true,有一个false就返回false
Array.some的条件是「或」的关系,有真为真,条件有一个true就返回true,条件全为false的时候才返回false
下面举个:chestnut:
// 判断每个名字都为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)) // 看掘金小册前端面试指南看到的 // 这个加缓存的方法看到的时候很惊艳,我知道递归可以解决,但是没有想过加缓存优化 function fn(n) { let cache = {}; function _fn(n) { if (cache[n]) { return cache[n]; } 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); } // 常规无缓存的方法 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]; } } } 复制代码
完!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- LFU五种实现方式,从简单到复杂
- LFU 五种实现方式,从简单到复杂
- 从简单二叉树问题重新来看深度优先搜索
- 从简单日志到全链路日志 我们应该怎么打日志
- 从简单的即时聊天来看架构演变by golang
- 记一次筛选重构
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Foundations of PEAR
Good, Nathan A./ Kent, Allan / Springer-Verlag New York Inc / 2006-11 / $ 50.84
PEAR, the PHP Extension and Application Repository, is a bountiful resource for any PHP developer. Within its confines lie the tools that you need to do your job more quickly and efficiently. You need......一起来看看 《Foundations of PEAR》 这本书的介绍吧!
随机密码生成器
多种字符组合密码
HSV CMYK 转换工具
HSV CMYK互换工具