在上家公司工作的时候,有一个需求是在前端部分完成筛选功能,一次拿到所有数据,然后根据条件筛选。通常情况下筛选是后台给接口,在数据量不大的情况下,也有人可能会遇到前端筛选这样的情况,特别写了这篇文章分享给大家,有问题请指出,互相学习。

一般情况下的单条件筛选,数组的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 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

下面举个🌰

// 判断每个名字都为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 数组过滤内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

JS实现数组过滤从简单到多条件筛选的更多相关文章

  1. html5 拖拽及用 js 实现拖拽功能的示例代码

    这篇文章主要介绍了html5 拖拽及用 js 实现拖拽,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. amaze ui 的使用详细教程

    这篇文章主要介绍了amaze ui 的使用详细教程,本文通过多种方法给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. swift皮筋弹动发射飞机ios源码

    这是一个款采用swift实现的皮筋弹动发射飞机游戏源码,游戏源码比较详细,大家可以研究学习一下吧。

  4. Swift与Js通过WebView交互

    开发环境:Swfit2.3XCode8.2基础概念jscontext,jscontext是代表JS的执行环境,通过-evaluateScript:方法就可以执行一JS代码JSValue,JSValue封装了JS与ObjC中的对应的类型,以及调用JS的API等JSExport,JSExport是一个协议,遵守此协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来,才能调用Swif

  5. JSCore swift

    如果双方相互引用,会造成循环引用,而导致内存泄露。以上是Jscore的基本使用,比较简单

  6. Swift WKWebView的js调用swift

    最近项目需求,需要用到JavaScriptCore和WebKit,但是网上的资源有限,而且比较杂,都是一个博客复制另外一个博客,都没有去实际敲代码验证,下面给大家分享一下我的学习过程。

  7. Swift WKWebView的swift调用js

    不多说,直接上代码:在html里面要添加的的代码,显示swift传过去的参数:这样就实现了swift给js传参数和调用!

  8. 在 Swift 專案中使用 Javascript:編寫一個將 Markdown 轉為 HTML 的編輯器

    你有強烈的好奇心,希望在你的iOS專案中使用JavaScript。jscontext中的所有值都是JSValue對象,JSValue類用於表示任意類型的JavaScript值。因此,我們既需要寫Swift代碼也要寫JavaScript代碼。此外,我們還會在JavaScript中按照這個類的定義來創建一個對象并對其屬性進行賦值。從Swift中呼叫JavaScript就如介紹中所言,JavaScriptCore中最主要的角色就是jscontext類。一個jscontext對象是位於JavaScript環境和本

  9. swift - WKWebView JS 交互

    本文介绍WKWebView怎么与js交互,至于怎么用WKWebView这里就不介绍了HTML代码APP调JS代码结果JS给APP传参数首先注册你需要监听的js方法名2.继承WKScriptMessageHandler并重写userContentController方法,在该方法里接收JS传来的参数3.结果

  10. swift 开发UIWebView跟JS的交互

    前言作为小白的我,才开始入门IOS,选择了swift来进行入门学习,学习做着公司一个简单的小小项目,该项目需要进行跟H5进行交互,然后我就开始研究了UIWebView的使用,其实基本原理跟Android的一样,因为我是Android开发的,所以就顺水推舟了。))//这里设置你需要加载的地址}overridefuncdidReceiveMemoryWarning(){super.didReceiveMemoryWarning()//disposeofanyresourcesthatcanberecreate

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部