How to optimize multiple filter? - javascript

I have big search panel with filters
In the computed section I use the next code
computed: {
filteredItems() {
if (this.activeFilter && this.activeFilter != 'all') {
return this.items[this.activeFilter]
.filter(item => item.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1)
.filter(item => item.itemLevel >= this.minLvl && item.itemLevel <= this.maxLvl);
} else {
let all = [];
let i;
if (this.items) {
for (i = 0; i < this.filters.length; i++) {
Array.prototype.push.apply(all, this.items[this.filters[i].value]);
}
}
return all
.filter(item => item.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1)
.filter(item => {
if (this.minLvl !== '' && this.maxLvl !== '') {
if (item.itemLevel >= this.minLvl && item.itemLevel <= this.maxLvl) return true;
} else if (this.minLvl == '' && this.maxLvl !== '') {
if (item.itemLevel <= this.maxLvl) return true;
} else if (this.minLvl !== '' && this.maxLvl == '') {
if (item.itemLevel >= this.minLvl) return true;
} else {
return true;
}
});
}
},
}
Here is I use one filter for min and max level. And when I will add more filter my code will be too big. Multiple filters can be active l at the same time.
How can I optimize my code?

Related

How i can optimize this code, whithout creating variable `a`?

Help to optimize below functions, whithout creating variable a
getFieldsGroups(){
let a = [];
if(this.activeTab.fieldsGroupName === ''){
this.activeTab = {
groupIndex: 0,
subgroupIndex: 0,
fieldsGroupName: this.groups[0][0].name
}
}
this.groups.forEach((group, groupIndex) => {
group.forEach((fieldsGroup, fieldsGroupIndex) => {
if(
groupIndex == this.activeTab.groupIndex &&
fieldsGroup.name == this.activeTab.fieldsGroupName
){
a.push(fieldsGroup);
}
})
})
return a.length == 1 ? [] : a;
}
getFields(){
let a;
this.groups.forEach((group, groupIndex) => {
group.forEach((fieldsGroup, fieldsGroupIndex) => {
if(
groupIndex == this.activeTab.groupIndex &&
fieldsGroup.name == this.activeTab.fieldsGroupName
){
if(this.activeFieldsGroup.name === '' && fieldsGroup.name === this.activeTab.fieldsGroupName){
a = group.filter(_fieldsGroup => _fieldsGroup.name === this.activeTab.fieldsGroupName)[0];
}else if(fieldsGroup.label == this.activeFieldsGroup.label){
a = fieldsGroup;
}
}
})
})
return a.fields.length == 1 ? [] : a.fields;
},

How to drastically improve this if else if

I'm trying to improve this code from all of these else if statements to a switch or something more efficient.
renderIconType = () => {
const { icons = {} } = this.props;
const percent = courseDataStore.getComponentCompletionPercentage(this.props.linkedNodeId);
const isHovering = this.state.isHovering;
const isStarted = !!courseDataStore.getComponentCompletionPercentage(this.props.linkedNodeId);
const isCompleted = percent >= 1;
if (isStarted && isCompleted) {
return icons.completed
} else if (isStarted && isCompleted && isHovering) {
return icons.completedHover
} else if (!isStarted && !isCompleted && isHovering) {
return icons.notStartedHover
} else if (isStarted && !isCompleted && isHovering) {
return icons.startedHover
} else if (isStarted && !isCompleted && !isHovering) {
return icons.started
} else if (!isStarted && !isCompleted && !isHovering) {
return icons.notStarted
}
}
This currently works for my intents and purposes but pains me to look at it lol. I tried a switch statement but that doesn't work.

Render text depending on matching API Results - Axios/JS

I have this working, but it does consume quite a lot of space.
I'm wondering if there is way to refactor it more, matching API results with a smaller refactored condition, perhaps?
axios.js
import axios from 'axios';
export const Models = () => {
return axios.get('data/cars.json')
.then(response => {
return response.data
})
}
file.js
import { Models } from './axios';
let carModels = Models();
carModels.then((result) => {
var i, j, match;
match = false;
for (i = 0; i < result.length; i++) {
for (j = 0; j < result[i].countries.length; j++) {
if (result[i].countries[j].price == price &&
result[i].color == color &&
result[i].brand == brand &&
result[i].model == model &&
result[i].speed == speed)
{
match = true;
return document.querySelector('#brandTitle').textContent = result[i].brand;
}
}
}
if (match == false) {
console.log('No match found.');
}
})
you can use some() that will make sure to terminate the loop as conditions met
carModels.then(result => {
var i, j, match;
match = false;
for (i = 0; i < result.length; i++) {
match = result[i].countries.some(country => {
if (
country.price == price &&
result[i].color == color &&
result[i].brand == brand &&
result[i].model == model &&
result[i].speed == speed
) {
document.querySelector('#brandTitle').textContent = result[i].brand;
return;
}
});
}
if (match == false) {
console.log('No match found.');
}
});
to make more efficient you can use some on parent loop also
carModels.then(result => {
var match;
match = false;
result.some(res => {
match = result[i].countries.some(country => {
if (
country.price == price &&
res.color == color &&
res.brand == brand &&
res.model == model &&
res.speed == speed
) {
document.querySelector('#brandTitle').textContent = res.brand;
return;
}
});
if (match) {
return;
}
});
if (match == false) {
console.log('No match found.');
}
});

How to create correct multiple filter?

I am trying to show items of game and I want to filter my output results.
I have panel with multiple filters
And I don't know how to do it correct. Some filters are similar, maybe it should move to function.
I tried to do like this (for search by name and one filter), but I am not sure is it the best way or no?
filteredItems() {
if (this.activeFilter && this.activeFilter != "all") {
return this.items[this.activeFilter]
.filter(
item =>
item.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1
)
.filter(item => {
if (this.minLvl !== "" && this.maxLvl !== "") {
if (
item.itemLevel >= this.minLvl &&
item.itemLevel <= this.maxLvl
)
return true;
} else if (this.minLvl == "" && this.maxLvl !== "") {
if (item.itemLevel <= this.maxLvl) return true;
} else if (this.minLvl !== "" && this.maxLvl == "") {
if (item.itemLevel >= this.minLvl) return true;
} else {
return true;
}
});
}

creating a javascript recursive filter function

Is there any way of making this function recursive so that I do not need to create a switch for each length of filter criteria ?
var data = [
{a:'aaa',b:'bbb',c:'ccc',d:'ddd',e:'eee'},
{a:'aaa',b:'bbb',c:'ccc',d:'eee',e:'fff'},
{a:'xxx',b:'bbb',c:'ccc',d:'ddd',e:'fff'}
]
function select(data,where){
return data.filter(function(e){
var k = Object.keys(where);
switch(k.length){
case 1: return (e[k[0]] == where[k[0]]);
case 2: return (e[k[0]] == where[k[0]] && e[k[1]] == where[k[1]]);
case 3: return (e[k[0]] == where[k[0]] && e[k[1]] == where[k[1]] && e[k[2]] == where[k[2]]);
case 4: return (e[k[0]] == where[k[0]] && e[k[1]] == where[k[1]] && e[k[2]] == where[k[2]] && e[k[3]] == where[k[3]]);
case 5: return (e[k[0]] == where[k[0]] && e[k[1]] == where[k[1]] && e[k[2]] == where[k[2]] && e[k[3]] == where[k[3]] && e[k[4]] == where[k[4]]);
}
})
}
var where = {a:'aaa',b:'bbb'}
console.log(select(data,where));
It doesn't need to be recursive (I'm not sure you understand what that means), you just need to loop on the elements in where:
function select(data, where) {
return data.filter(function(e) {
var k = Object.keys(where);
return k.every(function(key) {
return e[key] == where[key];
});
})
}
var data = [
{a:'aaa',b:'bbb',c:'ccc',d:'ddd',e:'eee'},
{a:'aaa',b:'bbb',c:'ccc',d:'eee',e:'fff'},
{a:'xxx',b:'bbb',c:'ccc',d:'ddd',e:'fff'}
]
var where = {a:'aaa',b:'bbb'}
console.log(select(data,where));
Try this code:
function select(data, where) {
return data.filter(function (e) {
for (var key in where) {
if (where.hasOwnProperty(key)) {
if (e.hasOwnProperty(key)) {
if (e[key] != where[key]) {
return false;
}
}
else {
return false
}
}
}
return true;
})
}

Categories

Resources