JS前端数据多条件筛选(商品搜索)

摘要:
有时候也会需要在前端进行数据筛选,增强交互体验。当数据可用的筛选条件较多时,把逻辑写死会给后期维护带来很大麻烦。进行商品按条件筛选主要是利用Arrary.prototype.filter对数组元素进行遍历检查,返回一个符合检查条件的新数组,不会改变原数组。为了能自动适配不同的筛选条件,将筛选条件分为两个大类,一个是区间类型rangesFilter,如:品牌、内存等;一个是选择类型choosesFilter,如:价格、屏幕尺寸等。

有时候也会需要在前端进行数据筛选,增强交互体验。当数据可用的筛选条件较多时,把逻辑写死会给后期维护带来很大麻烦。下面是我自己写的一个简单的筛选器,筛选条件可以根据数据包含的字段动态设置。

仿照京东的筛选条件,这里就取价格区间和品牌作为测试。进行商品按条件筛选主要是利用Arrary.prototype.filter对数组元素进行遍历检查,返回一个符合检查条件的新数组,不会改变原数组。

JS前端数据多条件筛选(商品搜索)第1张

首先定义一个商品类:

// 定义商品类
function Product(name, brand, price) {
    this.name = name;  // 名称
    this.brand = brand;   // 品牌
    this.price = price;  // 价格
}

创建一个过滤器对象,把所有过滤数据的方法放在里面。为了能自动适配不同的筛选条件,将筛选条件分为两个大类,一个是区间类型rangesFilter,如:品牌、内存等;一个是选择类型choosesFilter,如:价格、屏幕尺寸等。

不同大类同时筛选时,进行的是与逻辑,每个大类在上一个大类筛选结果上进行筛选。比如我要筛选2000-5000块的华为手机,先调用rangesFilter筛选products并返回结果result1,然后用choosesFilter筛选result1并返回结果resulte2

如果还有其它大类,不一定是与逻辑,再另行处理。

//商品筛选器
const ProductFilters ={
    /**
     * 区间类型筛选
     * @param {array<Product>} products
     * @param {array<{type: String, low: number, high: number}>} ranges
     */rangesFilter: function(products, ranges) { } 

    /**
     * 选择类型筛选
     * @param {array<Product>} products
     * @param {array<{type: String, value: String}>} chooses
     */choosesFilter: function(products, chooses) { }
}

区间类型的筛选,代码如下:

// 区间类型条件结构
ranges: [
        {
            type: 'price',  // 筛选类型/字段
            low: 3000,  // 最小值
            high: 6000  // 最大值
        }
    ]
/**
     * @param {array<Product>} products
     * @param {array<{type: String, low: number, high: number}>} ranges
     */rangesFilter: function(products, ranges) {
        if (ranges.length === 0) {
            returnproducts;
        } else{
            /**
             * 循环多个区间条件,
             * 每种区间类型应该只有一个,
             * 比如价格区间不会有1000-2000和4000-6000同时需要的情况
             */
            for(let range of ranges) {
                //多个不同类型区间是与逻辑,可以直接赋值给自身
                products = products.filter(function(item) {
                    return item[range.type] >= range.low && item[range.type] <=range.high;
                });
            }
            returnproducts;
        }
    }

选择类型筛选:

//选择类型条件结构
chooses: [
        {
            type: 'brand',
            value: '华为'},
        {
            type: 'brand',
            value: '苹果'}
    ]
/**
     * @param {array<Product>} products
     * @param {array<{type: String, value: String}>} chooses
     */choosesFilter: function(products, chooses) {
        let tmpProducts =[];
        if (chooses.length === 0) {
            tmpProducts =products;
        } else{
            /**
             * 选择类型条件是或逻辑,使用数组连接concat
             */
            for(let choice of chooses) {
                tmpProducts = tmpProducts.concat(products.filter(function(item) {
                    return item[choice.type].indexOf(choice.value) !== -1;
                }));
            }
        }
        returntmpProducts;
    }

定义一个执行函数doFilter(),

functiondoFilter(products, conditions) {
    //根据条件循环调用筛选器里的方法
    for (key inconditions) {
        //判断是否有需要的过滤方法
        if (ProductFilters.hasOwnProperty(key + 'Filter') && typeof ProductFilters[key + 'Filter'] === 'function') {
            products = ProductFilters[key + 'Filter'](products, Conditions[key]);
        }
    }
    returnproducts;
}
//将两种大类的筛选条件放在同一个对象里
let Conditions ={
    ranges: [
        {
            type: 'price',
            low: 3000,
            high: 6000}
    ],
    chooses: [
        {
            type: 'brand',
            value: '华为'}
    ]
}

测试

创建10个商品数据,以及筛选条件

// 商品数组
const products = [
    new Product('华为荣耀9', '华为', 2299),
    new Product('华为P10', '华为', 3488),
    new Product('小米MIX2', '小米', 3599),
    new Product('小米6', '小米', 2499),
    new Product('小米Note3', '小米', 2499),
    new Product('iPhone7 32G', '苹果', 4588),
    new Product('iPhone7 Plus 128G', '苹果', 6388),
    new Product('iPhone8', '苹果', 5888),
    new Product('三星Galaxy S8', '三星', 5688),
    new Product('三星Galaxy S7 edge', '三星', 3399),
];
// 筛选条件
let Conditions = {
    ranges: [
        {
            type: 'price',
            low: 3000,
            high: 6000
        }
    ],
    chooses: [
        {
            type: 'brand',
            value: '华为'
        },
        {
            type: 'brand',
            value: '苹果'
        }
    ]
}  

调用函数:

let result =doFilter(products, Conditions);
console.log(result);

参考

免责声明:文章转载自《JS前端数据多条件筛选(商品搜索)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【Lua】使用随机数(转)Activiti-个人任务下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

.NET Core项目部署时自定义端口号

我会在有时间的时候总结Linux系统的部署。NETCore项目只使用这种方法。5.IIS部署项目。指定端口号环境:Windows。NET开发人员应该熟悉IIS吗。当我们使用IIS部署Core项目时,它与之前的Framework项目的部署类似。您可以自定义端口号。...

数据不平衡的相关

大多数常见的机器学习算法不能很好地处理不平衡的数据集。例如,搜索引擎的点击预测(点击页面往往占很小的比例)、电子商务中的产品推荐(正在购买的推荐产品的比例很低)、信用卡欺诈检测、网络攻击识别、癌症检测等。处理数据不平衡的方法主要有以下几种。2.数据级别2.1重新采样2.1.1欠采样(下采样)欠采样通过减少丰富类的大小来平衡数据集。它试图通过增加稀有样本的数量...

LaTex学习笔记(1)——LaTeX文档插入图片的几种常用方法

2,插入bmp图片还没有找到直接插入bmp图片的方法。用gimp或fastoneimageviewer,将jpg质量选为最高,转换之后得到的图片质量较好。3,同时插入jpg和eps图片插入的命令不变。编译时使用Latex,dvi2pdf,两种格式的图片都可以显示。...

java 服务接口API限流 Rate Limit

服务接口的流量控制策略:分流、降级、流量限制等。2)使用Reids的列表结构,而不是incr命令1FUNCTIONLIMIT_API_CALLL2current=LLEN3IFcurrent˃10THEN4ERROR“toomanyrequestsperssecond”5ELSE6IFEXIST==FALSE7MULTI8RPUSH9EXPIRE10EXEC...

Nohup后台运行程序

场景:我现在需要跑脚本批量处理一些数据,但是我又不想盯着控制台看这个脚本的输出结果,想把这些输出结果记录到一个日志文件里面方案:可以使用Linux的nohup命令,把进程挂起,后台执行用法:$nohupXXXXXX.sh˃˃/runtime/deletedata.log&运行结果(这个数字是进程号):˃˃[1]13120有时候可能会报一个提示:$no...

LaTeX表格tabular背景色添加技巧 [转]

我们所用的宏包为colortbl,这个宏包可以设置表格中数据、文本、行、列、单元格前景和背景以及边框的颜色,从而得到彩色表格。同时需要array和color两个宏包的支持。宏包提供了一组着色命令,经常用到是列着色命令,其格式为:\columncolor[色系]{色名}[左伸出][右伸出]。常用色系有三原色rgb灰度gray和四色cmyk三种;被预定义的色名有...