Search array of objects for entry matching variabl

2020-01-26 12:01发布

问题:

So the program is trying to allocate a classroom. So far, the program has asked the user for class code, number of students and whether computers are required, and an array has been built with the fields "cRObj.name", "cRObj.students" and cRObj.computers" (so a classroom name will be listed under cRObj.name, number of student capacity under cRObj.students and whether or not it has computers (y/n) in cRObj.computers).

I've got to search the array of objects to try find an entry that matches the number of students the user has entered (which I think I know how to do).

However, after then it needs to check the cRObj.computers is equal to the user's input and then save the entry under cRObj.name if the first two match, which I am unsure on how to do.

回答1:

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))
)