Search array of objects for entry matching variable and check if it matches other fields

You can use array.filter, this takes a function that is passed each item of the array and returns true or false and returns a new array that only has items where the function passed to filter will return true.

You can partially apply a curried function. Example of curried function:

const plus = a => b => a+b;
const plusTen = plus(10);//is a function that takes number b and adds 10 (a is 10)
const eleven = plusTen(1); takes 1 for value of b and 10 for value of a

Here is how you can use curried function for comparing:

const equal = search => value =>
  search === value;
const isFive = equal(5);
//... this will return false, search is 5 and value is 10
//  5===10 is false
if(isFive(10)){

Provide a function that will get a property from an object:

const getA = o => (o&&o.a);
getA({a:10};//will return 10
getA({hasNoA:10};//will return undefined

Combine all to create a filter function:

const data = [
  {a:3,b:2},
  {a:4,b:6},
  {a:5,b:8},
  {a:6,b:9},
  {a:7,b:3}
];

//filer function needs a getter (like getA)
// comparer that is a partially applied function that takes a value and compares it
//   with o.something (if getter is getA it'll compare with o.a)
// o is the object that needs to be filtered (like elements of data: data[0]={a:3,b:2})  
const filterFn = getter => comparer => o =>
  comparer(getter(o));

//get a property
const getA = o => (o&&o.a);
//you can write getB I'm sure

// compare search === value
const equal = search => value =>
  search === value;

// compare search <= value
const biggerEqual = search => value =>
  search <= value;

// all data items where item.a === 5
console.log(
  "a is 5",
  data.filter(
    filterFn(getA)(equal(5))//partially apply equal with search of 5
  )
);

//all data items where item.a >= 5
console.log(
  "a equals or bigger 5",
  data.filter(
    filterFn(getA)(biggerEqual(5))//partially apply biggerEqual with search of 5
  )
);

//if you want to compare b with some things you could do
// const getB = o => (o&&o.b);
// data
//  .filter(filterFn(getA)(biggerEqual(5)))//a bigger or equal 5
//  .filter(filterFn(getB)(can you guess?)//b equal 5

// here is an example that takes an array of data and an array of filter functions
//  it'll apply filter on array of data for every function
const filterData = (array, filterFunctions) =>
  filterFunctions.reduce(
    (result,filterFunction)=>result.filter(filterFunction),
    array
  );
// using filterData
console.log(
  "using filterData",
  filterData(data,[
    filterFn(getA)(biggerEqual(5))//partially apply biggerEqual with search of 5
    //,you could add more filters here
  ])
)

For a more complex comparer (like wanting to know if a value of the object is in a list of values) you can do the following:

const filterFn = getter => comparer => o =>
  comparer(getter(o));
const data= [{id:23},{id:11},{id:435}];
const values= [23, 435, 5];

const getId = o => o.id;
const isIn = haystack => needle => haystack.includes(needle);
const isInValues = isIn(values);
console.log(
  data.filter(filterFn(getId)(isInValues))
)

Leave a Comment