Home > front end >  Filtering an array of objects by a number property value (range of values)
Filtering an array of objects by a number property value (range of values)

Time:07-03

I have an array of objects with a list of courses and their prices.

const courses = [
  { name: "Courses in England",    prices: [   0,  100] }, //1st object
  { name: "Courses in Germany",    prices: [ 500, null] }, //2nd object
  { name: "Courses in Italy",      prices: [ 100,  200] }, //3rd object
  { name: "Courses in Russia",     prices: [null,  400] }, //4th object
  { name: "Courses in China",      prices: [  50,  250] }, //5th object
  { name: "Courses in USA",        prices: [ 200, null] }, //6th object
  { name: "Courses in Kazakhstan", prices: [  56,  324] }, //7th object
  { name: "Courses in France",     prices: [null, null] }, //8th object
];

Here I used the filter method, which kinda works when I want to filter by the course name property.

const filter = courses.filter((obj) => {
  return obj.name === "Courses in England";
});
console.log(filter);
returns // { name: "Courses in England", prices: [0, 100] }

Here i used the for loop to get all the objects in the courses array.

const filter = function (arr) {
  for (let i = 0; i < arr.length; i  ) {
    console.log(arr[i]);
  }
};
filter(courses);

I can't figure out how to modify the Filter function to accept the prices property which has 2 number element values [100, 200] and for it to only return similar objects in the array with similar range of prices property.

My goal is as follows. For example, when I pass the number 100
it should return:

{ name: "Courses in England", prices: [ 0, 100] } 
{ name: "Courses in Italy", prices: [ 100, 200] } 

because both objects have the value 100.

CodePudding user response:

  1. To return

the prices property which has 2 number element values

loop through all the objects and check that the value for the prices property all has the type of number and return such object.

    const result = courses.filter(({ prices }) => 
          prices.every(price => typeof price === "number"))
    
    console.log(result)
    // With love @kouqhar
  1. And

for it to only return similar objects in the array with similar range of prices property

you can provide a range of number(s) and then loop through the result filtering the range.

E.g Range of Number between 100 - 500 Your final code will look like the code example below, be free to type with this (price >= 100 && price <= 500) also the && operator with ||

     const result = courses.filter(({ prices }) => 
           prices.every(price => 
              typeof price === "number" && (price >= 100 && price <= 500)))

     console.log(result)
  // With love @kouqhar

CodePudding user response:

that ?

usage is :

let answerArray = courses.filtering( argument_value )
  • if argument_value is a string,
    the answer search all elements where name === argument_value

  • if argument_value is an array,
    the answer search all elements where prices array is the same as argument_value array

  • if argument_value is null numeric (integer or float)
    the answer search all elements where the prices array includes a null value

- if `argument_value` is an integer, the answer search all elements where `prices array range` contains the `argument_value`

const courses =
  [ { name: 'Courses in England',    prices: [   0,  100] } // 1st object
  , { name: 'Courses in Germany',    prices: [ 500, null] } // 2nd object
  , { name: 'Courses in Italy',      prices: [ 100,  200] } // 3rd object
  , { name: 'Courses in Russia',     prices: [null,  400] } // 4th object
  , { name: 'Courses in China',      prices: [  50,  250] } // 5th object
  , { name: 'Courses in USA',        prices: [ 200, null] } // 6th object
  , { name: 'Courses in Kazakhstan', prices: [  56,  324] } // 7th object
  , { name: 'Courses in France',     prices: [null, null] } // 8th object
  ];

courses.filtering = filter_Key => 
  {
  if (typeof(filter_Key) === 'string')
    return courses.filter(obj => obj.name === filter_Key)

  if (Array.isArray(filter_Key))
    return courses.filter(obj => JSON.stringify(obj.prices) === JSON.stringify(filter_Key))

  if (filter_Key===null || Number.isFinite(filter_Key))
    return courses.filter(obj => obj.prices.includes(filter_Key))

  // if (Number.isInteger(filter_Key))
  //   return courses.filter(obj => 
  //     {
  //     let [min,max] = [...obj.prices].sort((a,b)=>a-b)
  //     if (min===null) min = max || 0
  //     if (max===null) max= -1

  //     return ( min <= filter_Key  && filter_Key <= max )
  //     })
 
  // anything else...
  return []    
  };
  
  
console.log('Courses in England ->\n'   JSON.stringify(courses.filtering( 'Courses in England' )))

console.log('\n[100, 200] ->\n'   JSON.stringify(courses.filtering( [100, 200] )))

console.log('\n100 ->\n'   JSON.stringify(courses.filtering( 100 )).replaceAll('},{','}\n,{'))

console.log('\nnull ->\n'   JSON.stringify(courses.filtering( null )).replaceAll('},{','}\n,{'))
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}

  • Related