Skip to content

Instantly share code, notes, and snippets.

@erineland
Created July 5, 2019 10:33
Show Gist options
  • Save erineland/714bc2bec56f968a483867a4e8908191 to your computer and use it in GitHub Desktop.
Save erineland/714bc2bec56f968a483867a4e8908191 to your computer and use it in GitHub Desktop.
Small utility to create a customisable utility for filtering an array of people objects.

This is a small utility designed to take an array of people objects, each with name, age and gender as well as an optional set of rules for filtering those objects, and return the filtered list, grouped by the genders of the people.

By default, if no custom rules are passed in, only people between the ages of 30 and 40 will be returned.

Run and read the tests to see different inputs and outputs.

Here's an example:

const peopleFilter = require('../src/people-filter');
const youngerMalePeople = [
    {
        name: 'Dave',
        age: 25,
        gender: 'Male',
    },
]
const olderMalePeople = [
    {
        name: 'Josh',
        age: 30,
        gender: 'Male',
    },
    {
        name: 'John',
        age: 31,
        gender: 'Male'
    },
]
const malePeople = [
    ...olderMalePeople,
    ...youngerMalePeople,
];

const filteredPeopleDefaultRules = peopleFilter(malePeople);

console.log(JSON.stringify(filteredPeopleDefaultRules));
// Will be the 'olderMalePeople' array

const customRules = ['personToFilter.age >= 20 && personToFilter.age < 30'];
const youngerPeople = peopleFilter(testPeopleToFilter, customRules);

console.log(JSON.stringify(youngerPeople));
// Will be the 'youngerMalePeople' array
filterAndGroupByGender = (personToFilter, filteredPeopleGroupedByGender, ruleToUse) => {
if (eval(ruleToUse)) {
if (filteredPeopleGroupedByGender[personToFilter.gender]) {
const existingArray = filteredPeopleGroupedByGender[personToFilter.gender];
existingArray.push(personToFilter);
filteredPeopleGroupedByGender[personToFilter.gender] = existingArray;
} else {
const newGenderArray = [];
newGenderArray.push(personToFilter);
filteredPeopleGroupedByGender[personToFilter.gender] = newGenderArray;
}
}
}
module.exports = (peopleToFilter, customRules) => {
if (!peopleToFilter) {
throw new Error('Please supply a valid list of people objects.');
}
const defaultRule = 'personToFilter.age >= 30 && personToFilter.age <= 40';
let rulesToUse = [];
if (!customRules) {
rulesToUse.push(defaultRule);
} else {
rulesToUse = rulesToUse.concat(customRules);
}
const filteredPeopleGroupedByGender = {};
peopleToFilter.forEach(personToFilter => {
rulesToUse.forEach(rule => {
filterAndGroupByGender(personToFilter, filteredPeopleGroupedByGender, rule);
})
});
return filteredPeopleGroupedByGender;
}
const peopleFilter = require('../src/people-filter');
const youngerMalePeople = [
{
name: 'Dave',
age: 25,
gender: 'Male',
},
]
const olderMalePeople = [
{
name: 'Josh',
age: 30,
gender: 'Male',
},
{
name: 'John',
age: 31,
gender: 'Male'
},
]
const malePeople = [
...olderMalePeople,
...youngerMalePeople,
];
const femalePeople = [
{
name: 'Brody',
age: 40,
gender: 'Female',
},
{
name: 'Cersei',
age: 35,
gender: 'Female'
},
{
name: 'Jess',
age: 36,
gender: 'Female',
},
];
const nonBinaryPeople = [
{
name: 'Varys',
age: 39,
gender: 'Non-binary'
}
];
const testPeopleToFilter = [
...malePeople,
...femalePeople,
...nonBinaryPeople
]
describe('People Filter Utility', () => {
describe('When an array of people objects is not passed in', () => {
it('Throws an error with a meaningful error message', () => {
try {
const filteredNonPeople = peopleFilter();
} catch (filterError) {
expect(filterError.message)
.toBe('Please supply a valid list of people objects.');
}
});
});
describe('When a valid array of people objects is passed in', () => {
describe('When filtering using the default rules', () => {
it('Returns male gendered people between the age of 30 and 40', () => {
const filteredPeople = peopleFilter(testPeopleToFilter);
expect(filteredPeople['Male']).toEqual(olderMalePeople);
});
it('Returns the female gendered people between the age of 30 and 40', () => {
const filteredPeople = peopleFilter(testPeopleToFilter);
expect(filteredPeople['Female']).toEqual(femalePeople);
});
it('Returns the non-binary gendered people between the age of 30 and 40', () => {
const filteredPeople = peopleFilter(testPeopleToFilter);
expect(filteredPeople['Non-binary']).toEqual(nonBinaryPeople);
});
});
describe('Takes a set of custom rules used to filter people', () => {
it('Uses the custom rules passed in', () => {
const customRules = [];
customRules.push('personToFilter.age >= 20 && personToFilter.age < 30');
const youngerPeople = peopleFilter(testPeopleToFilter, customRules);
expect(youngerPeople['Male']).toEqual(youngerMalePeople);
});
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment