多个角度搜索过滤器

时间:2020-07-01 10:17:16

标签: javascript angular typescript

我创建了3个搜索字段:1.名称.... 2.主题.... 3.价格....
如果单独考虑,所有这些都工作良好。例如。从元素列表中,如果我按名称搜索,则从该名称获得所有结果,或者如果我按主题搜索,则得到该主题的所有结果,并且价格也相同。

< strong>但是问题是我不知道如何让所有过滤器同时为我工作,即如果我想要一个叫“ BOB”的人可以以“ 500-600”的价格教“英语” 。如何实现多个过滤器之间的链接 This is the image of my filter

component.ts
filterSearch一个包含用户所有数据的数组,并且tempFilterSearch用于在html

上显示它
searchSubject($event) {
    this.subject = $event.target.value;
    if(this.price == null){
        this.tempFilterSearch = this.filterSearch.filter((res) => {         
            return (                    
                res.subject1.toLocaleLowerCase().match(this.subject.toLocaleLowerCase()) ||
                res.subject2.toLocaleLowerCase().match(this.subject.toLocaleLowerCase()) ||
                res.subject3.toLocaleLowerCase().match(this.subject.toLocaleLowerCase())
                );
            });
    }else if(this.price != null){
        this.tempFilterSearch = this.filterSearch.filter((res)=>{
            console.log(res);
            if((Number(res.price1))>=(Number(this.lowerValue))
                &&(Number(res.price1))<=(Number(this.higherValue)) 
                &&(res.subject1.match(this.subject)) || (res.subject2.match(this.subject))|| (res.subject3.match(this.subject))){
                    return res.subject1 || res.subject2 || res.subject3;
            }
        })
    }

searchName() {  
    this.tempFilterSearch = this.filterSearch.filter((response)=>{
        return response.fullName.toLocaleLowerCase().match(this.name.toLocaleLowerCase());
    })
    
}

searchPrice($event) {
    this.price = $event.target.value.split("-");
    this.lowerValue = this.price[0];
    this.higherValue = this.price[1];
    if (this.subject == null) {
        this.tempFilterSearch = this.filterSearch.filter((res) => {
            if((Number(res.price1))>=(Number(this.lowerValue))&&(Number(res.price1))<=(Number(this.higherValue)))
                return res.price1.toLocaleLowerCase();
            });
    }else if(this.subject != null){
        this.tempFilterSearch = this.filterSearch.filter((res)=>{
            if((Number(res.price1))>=(Number(this.lowerValue))
                &&(Number(res.price1))<=(Number(this.higherValue)) ){
                    return res.price1.toLocaleLowerCase();
            }
        })
    }
}

component.html

 <div class="tutorWrapper" *ngFor="let element of tempFilterSearch">

我想要的是一个解决方案,以便所有过滤器可以同时工作。

2 个答案:

答案 0 :(得分:2)

在示例代码中,所有单独的过滤器都应用于新的this.filterSearch。这意味着,每次开始任何过滤时,它都会重置先前过滤的结果并从头开始。

您需要将过滤器合并为一种逻辑,以将所有滤镜应用于同一阵列,并且只有一个输出阵列。每当过滤器发生更改时,它将从原始数组开始,并一一应用所有过滤器。

例如;

searchSubject($event) {
    this.subject = $event.target.value;
    this.applyFilters();
}

searchName() {  
    //this.name is already assigned 
    this.applyFilters();    
}

searchPrice($event) {
    this.price = $event.target.value.split("-");
    this.lowerValue = this.price[0];
    this.higherValue = this.price[1];
    this.applyFilters();
}



applyFilters() {
    let temp = this.filterSearch;


    // SUBJECT
    if(this.price == null){
        temp = temp.filter((res) => {           
            return (                    
                res.subject1.toLocaleLowerCase().match(this.subject.toLocaleLowerCase()) ||
                res.subject2.toLocaleLowerCase().match(this.subject.toLocaleLowerCase()) ||
                res.subject3.toLocaleLowerCase().match(this.subject.toLocaleLowerCase())
                );
            });
    }else if(this.price != null){
        temp = temp.filter((res)=>{
            if((Number(res.price1))>=(Number(this.lowerValue))
                &&(Number(res.price1))<=(Number(this.higherValue)) 
                &&(res.subject1.match(this.subject)) || (res.subject2.match(this.subject))|| (res.subject3.match(this.subject))){
                    return res.subject1 || res.subject2 || res.subject3;
            }
        })
    }


    // NAME
    temp = temp.filter((response)=>{
        return response.fullName.toLocaleLowerCase().match(this.name.toLocaleLowerCase());
    })
    

    // PRICE
    if (this.subject == null) {
        temp = temp.filter((res) => {
            if((Number(res.price1))>=(Number(this.lowerValue))&&(Number(res.price1))<=(Number(this.higherValue)))
                return res.price1.toLocaleLowerCase();
            });
    }else if(this.subject != null){
        temp = temp.filter((res)=>{
            if((Number(res.price1))>=(Number(this.lowerValue))
                &&(Number(res.price1))<=(Number(this.higherValue)) ){
                    return res.price1.toLocaleLowerCase();
            }
        })
    }

    this.tempFilterSearch = temp;
}

未触碰您的单独过滤器功能,未测试逻辑。我只复制粘贴内容以将您的代码重新安排到合并的函数中。

答案 1 :(得分:0)

我正在通过电话回答此问题,因此如果此回答不够好​​,请稍后再从pc对其进行编辑。

我要做的方法是创建所有3个可能的过滤器作为函数。以您的案例名称,主题,价格, 并创建一个变量来保存过滤对象的数组。

在第一个过滤器(名称)上,我的函数将获取主列表数组,并将所有匹配的元素返回到过滤后的变量中。

然后主题过滤器将过滤后的变量应用于主题。并将输出重新分配回filteredarray。 价格也一样。

然后,您将筛选出的数组。

!!编辑!!

根据您对如何解决已过滤的阵列问题的评论。在下面写一些伪代码:

mainArray = [...arrayItems];

filteredArray: Items[];


onFilterButtonPressed(name, subject, price) {

 // here you can use if to see if some value hasnt been provided and skip that filter
  nameFilter();
  subjectFilter();
  priceFilter();
}


nameFilter(name){
  filteredArray = mainArray.filter(item => item.name === name)
}

subjectFilter(subject){
  filteredArray = filteredArray.filter(item => item.subject === subject)
}

priceFilter(price){
  filteredArray = filteredArray.filter(item => item.price === price)
}
<button (click)="onFilterButtonPressed(pass your filter values here)">click to filter</button

上面的代码很丑陋,需要有name变量,但是要解决的是,我们使用了管道函数,该函数使用reduce()来应用我们的过滤器

//here we create a function that uses reduce which takes the current array and applies the next filter function to it and changes that current array and so on
function pipe(...fns) {
  return (arg) => fns.reduce((prev, fn) => fn(prev), arg);
}
// here we call the function we made and pass the filter functions we created to it
//our filter functions must filter and return the filtered array, they also check whether the filter exists or not, if it doesnt then return the array unchanged
filteredArray =  pipe(nameFilter, subjectFilter, priceFilter)(MainArray)

希望这会有所帮助