Skip to content

Instantly share code, notes, and snippets.

@vcardins
Created May 17, 2017 08:05
Show Gist options
  • Save vcardins/496f450656f3db1213a60e6a67b1fa26 to your computer and use it in GitHub Desktop.
Save vcardins/496f450656f3db1213a60e6a67b1fa26 to your computer and use it in GitHub Desktop.
Location ranking filtering ( e.g 4,8-120,2,135-172)
getRules (query = '') {
const getValueRule = (values = []) => (val) => !values.length ? undefined : values.indexOf(val) > -1;
const getIntervalRule = (range = []) => (val) => !range.length ? undefined : val >= range[0] && val <= range[1];
const rules = [];
if (!arr.length) {
return rules;
}
// Split query by common and extract rules units
const values = query.split(',').filter(Boolean);
// Filter single rank (number) ones and convert to number
const numbers = values.filter(Number).map(Number) || [];
// Filter rank range ones
const nonNumbers = values.filter(isNaN) || [];
// Extract multiple possible intervals and convert to number
const intervals = nonNumbers.map((item) => item.split('-').filter(Number).map(Number) || []);
// Loop through array of intervals (can be multiple intervals e.g 2-20, 30-90, 120-380)
for (let i = 0, len = intervals.length; i < len; i++) {
// In case a dash separator has been ignore in the previous step, still filter by first number
// add it to the existing rank/number colletion
if (intervals[i].length === 1) {
numbers.push(intervals[i][0]);
}
// Add an interval calc rule if the interval has min and max
else {
rules.push(getIntervalRule(intervals[i]));
}
}
// Add rank/number calc rule
rules.push(getValueRule(numbers));
return rules.filter(Boolean);
}
const { rankQuery = '' } = this.state;
const filteredLocations = locations.reduce((result, location) => {
let include = true;
// If ranking has been set, check if is single or multiple criteria
if (include && rankQuery) {
// If rank is a simple number, match the location for that rank
if (!isNaN(rankQuery)) {
include = location.rank === rankQuery;
}
// If multiple criteria has been set, build rules list and apply them against locations
else {
const rules = this.getRules(rankQuery);
include = rules.reduce((result, rule) => result || rule(location.rank), false);
}
}
if (include) {
result.push(location);
}
return result;
}, []);
@willmendesneto
Copy link

Your get rules can be simplified using avoiding solve values twice in your application. There are other improvements, but I won't able to make those because I don't know the requirements.

get-rules.js

const getValueRule = (values = []) => (val) => !!values.length && values.indexOf(val) > -1;
const getIntervalRule = (range = []) => (val) => !!range.length && val >= range[0] && val <= range[1];
const convertStringInNumber = (item = []) => item.filter(Number).map(Number);

getRules (query = '') {
	// Where this `arr` is coming from?
	if (!arr.length) {
		return rules;
	}
	// Split query by common and extract rules units
	const values = query.split(',').filter(Boolean);
	// Filter single rank (number) ones and convert to number
	const numbers = convertStringInNumber(values);
	// Filter rank range ones
	const nonNumbers = values.filter(isNaN);
	// Extract multiple possible intervals and convert to number
	const intervals = nonNumbers.map((item) => convertStringInNumber(item.split('-')));

	return [].concat(
		intervals.filter((interval) => interval.length !== 1).map((interval) => getIntervalRule(interval)),
		intervals.filter((interval) => interval.length === 1).map((interval) => getValueRule(interval[0]))
	)
}

index.js

const { rankQuery = '' } = this.state;		
const filteredLocations = locations.reduce((result, location) => {
    let include; 
    // If ranking has been set, check if is single or multiple criteria
    if (rankQuery && !isNaN(rankQuery)) {
      include = location.rank === rankQuery;
    } 
    // If multiple criteria has been set, build rules list and apply them against locations
    else {
      const rules = this.getRules(rankQuery);
      include = rules.reduce((result, rule) => result || rule(location.rank), false);
    }
    return result.push(location);
  }, []);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment