margherita pizza
margherita pizza

Reputation: 7155

JavaScript filter by two parameters

const dates = [
{arrival_date:'2019-01-01',departure_date:'2019-01-07'},
{arrival_date:'2019-01-07',departure_date:'2019-01-09'},
{arrival_date:'2019-01-10',departure_date:'2019-01-20'}
];

let is_filter_by_arrival_date = true;
let is_filter_by_dept_date = true;

I have an array called dates. Also I have two Boolean variables is_filter_by_arrival_date and is_filter_by_dept_date.

Also I have another four variables.

let arrival_from = '';
let arrival_to = '';

let dept_from = '';
let dept_to = '';

What I want is if the Boolean variable is_filter_by_arrival_date is true. I need to filter my dates using arrival_from and arrival_to same as for the is_filter_by_dept_date.

What I have done up-to now is

let results = dates.filter(e => {if(is_filter_by_arrival_date){
    e.arrival_date <= arrival_to && e.arrival_date >= arrival_to
}})

But I want to filter not only by the is_filter_by_arrival_date. I want both is_filter_by_arrival_date and is_filter_by_dept_date.

How do I achieve this using JavaScript.

Upvotes: 1

Views: 841

Answers (5)

Jonas Wilms
Jonas Wilms

Reputation: 138307

Just use some boolean algebra. bypass || condition will evaluate to true if bypass is set, otherwise whatever condition is:

 const result = dates.filter(({ arrivalDate, departureDate }) => {

    const arrivalFits = arrivalDate <= arrivalTo && arrivalDate >= arrivalTo;
    const departureFits = departureDate <= departureTo && departureDate >= departureTo;

   return (!filterByArrival || arrivalFits) && (!filterByDeparture || departureFits);
});

Upvotes: 0

Marios Simou
Marios Simou

Reputation: 181

I can't really understand what do you want to achieve, however, I want to note:

  1. Within the callback function you can check the condition of your values.
  2. Return the values. At the moment you are not returning anything, and probably you are have an array with undefined values

Upvotes: 1

Avi
Avi

Reputation: 2069

You can use ternary operator like below for cleaner code

let results = dates.filter(e => {
  return (
    is_filter_by_arrival_date ? 
    // verify your condition for arrival date
    e.arrival_date <= arrival_to && e.arrival_date >= arrival_to 
    : 
    true
  ) && (
    is_filter_by_dept_date ? 
    // verify your condition for dept date
    : 
    true
  )
})

Upvotes: 0

Shilly
Shilly

Reputation: 8589

Just add the other filter as well? Also e.arrival_date <= arrival_to && e.arrival_date >= arrival_to is the same as e.arrival_date === arrival_to, since only that exact date can match. A date can never be both > and < than another date at the same time. So somthing like this might work:

const dates = [
  {arrival_date:'2019-01-01',departure_date:'2019-01-07'},
  {arrival_date:'2019-01-07',departure_date:'2019-01-09'},
  {arrival_date:'2019-01-10',departure_date:'2019-01-20'}
];

let is_filter_by_arrival_date = true;
let is_filter_by_dept_date = true;

let arrival_from = null;
let arrival_to = '2019-01-01';

let dept_from = null;
let dept_to = '2019-01-07';

let results = dates.filter( timeslot => {
  if ( is_filter_by_arrival_date && is_filter_by_dept_date ) {
    return timeslot.arrival_date === arrival_to && timeslot.departure_date === dept_to;
  }
  else if ( is_filter_by_arrival_date ) {
    return timeslot.arrival_date === arrival_to; 
  }
  else if ( is_filter_by_dept_date ) {
    return timeslot.departure_date === dept_to;
  }
  else throw new Error( 'no valid filters selected' );
});

console.log( results );

But I think you might have an error in your logic. If the idea is that the user can select a range of arrival and departure dates, hence else would you have both arrival_from and arrival_to, then you need to actually compare e.arrival_date <= arrival_to && e.arrival_date >= arrival_from instead of comparing to arrival_to both times. If this is true, then the code becomes:

const dates = [
  {arrival_date:'2019-01-01',departure_date:'2019-01-07'},
  {arrival_date:'2019-01-07',departure_date:'2019-01-09'},
  {arrival_date:'2019-01-10',departure_date:'2019-01-20'}
];

let is_filter_by_arrival_date = true;
let is_filter_by_dept_date = true;

let arrival_from = '2018-12-30';
let arrival_to = '2019-01-03';

let dept_from = '2019-01-07';
let dept_to = '2019-01-15';

let results = dates.filter( timeslot => {
  if ( is_filter_by_arrival_date && is_filter_by_dept_date ) {
    return timeslot.arrival_date >= arrival_from && timeslot.arrival_date <= arrival_to && timeslot.departure_date >= dept_from && timeslot.departure_date <= dept_to;
  }
  else if ( is_filter_by_arrival_date ) {
    return timeslot.arrival_date >= arrival_from && timeslot.arrival_date <= arrival_to
  }
  else if ( is_filter_by_dept_date ) {
    return timeslot.departure_date >= dept_from && timeslot.departure_date <= dept_to
  }
  else throw new Error( 'no valid filters selected' );
});

console.log( results );

The filter can be written shorter with ternaries and such as the other solutions show. But I preferred writing it out fully with if/else statements to make it more clear how the filter works.

Upvotes: 0

Jitesh Manglani
Jitesh Manglani

Reputation: 485

let results = dates.filter(e => {
  if(is_filter_by_arrival_date && is_filter_by_dept_date){
    return ( e.arrival_date <= arrival_to && e.arrival_date >= arrival_from &&
             e.departure_date <= dept_to && e.departure_date > = dept_from);
  }
  else if(is_filter_by_arrival_date){
    return e.arrival_date <= arrival_to && e.arrival_date >= arrival_from
  } else if(is_filter_by_dept_date) {
    return e.departure_date <= dept_to && e.departure_date > = dept_from
  }
  return true;
})

I think in your question you have just used arrival_to you should also make use of arrival_from. I have implemented according to my understanding.

Happy Coding!!

Upvotes: 0

Related Questions