Home > Mobile >  Filtering nested array against another nested array without loops
Filtering nested array against another nested array without loops

Time:07-23

I have a nested array I would like to compare and filter against another nested array.

const array1 = [
{
   id:1,
   nights: [{date: '2022-07-24', status: 'booked'},
            {date: '2022-07-26', status: 'booked'}]
},
{
   id:2,
   nights: [{date: '2022-07-24', status: 'booked'},
            {date: '2022-07-25', status: 'booked'}
            {date: '2022-07-26', status: 'booked'}]
}
];


const array2 = [
{
   id:1,
   days: [{date: '2022-07-24', breakdown: [...]},
          {date: '2022-07-25', breakdown: [...]},
          {date: '2022-07-26', breakdown: [...]}]
},
{
   id:2,
   days: [{date: '2022-07-24', breakdown: [...],
          {date: '2022-07-25', breakdown: [...],
          {date: '2022-07-26', breakdown: [...]}]
}
];

Essentially I want to filter array2 so it matches the dates in array1 and drops the extra day it has in the element with an id of 1.

The filtered array should look something like this:

const filteredArray2 = [
{
   id:1,
   days: [{date: '2022-07-24', breakdown: [...]},
          {date: '2022-07-26', breakdown: [...]}]
},
{
   id:2,
   days: [{date: '2022-07-24', breakdown: [...],
          {date: '2022-07-25', breakdown: [...],
          {date: '2022-07-26', breakdown: [...]}]
}
];

I have tried a couple of map, include, filter and reduce methods to achieve my desired output but I'm getting lost in the sauce with the nesting. First time posting and new to JS, any help is appreciated!

CodePudding user response:

Use find() to find the item in array1 with the matching id.

Then use filter() to filter the days array. The filter function uses .some() to check if there's a matching date in the nights array of the above item.

const array1 = [
{
   id:1,
   nights: [{date: '2022-07-24', status: 'booked'},
            {date: '2022-07-26', status: 'booked'}]
},
{
   id:2,
   nights: [{date: '2022-07-24', status: 'booked'},
            {date: '2022-07-25', status: 'booked'},
            {date: '2022-07-26', status: 'booked'}]
}
];


const array2 = [
{
   id:1,
   days: [{date: '2022-07-24', breakdown: []},
          {date: '2022-07-25', breakdown: []},
          {date: '2022-07-26', breakdown: []}]
},
{
   id:2,
   days: [{date: '2022-07-24', breakdown: []},
          {date: '2022-07-25', breakdown: []},
          {date: '2022-07-26', breakdown: []}]
}
];

const filteredArray2 = array2.map(item2 => {
  let item1 = array1.find(el => el.id == item2.id);
  if (item1) {
    let new_days = item2.days.filter(d => item1.nights.some(n => n.date = d.date));
    return { ...item2,
      days: new_days
    };
  } else {
    return { ...item2
    };
  }
});

console.log(filteredArray2);

CodePudding user response:

Since you want to transform the array, you want to use a map. Using flatMap will allow you to also filter out items by returning an empty array, [], if the ids aren't guaranteed to match.

const filteredArray2 = array2.flatMap(({ id, days}) => {

Inside of the flatMap, you want to find the corresponding object in array1 based on the id.

  const filterObject = array1.find((obj) => obj.id === id);

Now you want to do one of those things. If the item exists in array1, use it to filter the object in array2. Otherwise, ignore it by returning an empty array ([]).

  return filterObject ? [{
    id,
    days: days.filter((day) => filterObject.nights.find(night => day.date === night.date)) 
  }] : [];

Putting it all together

const array1 = [
{
   id:1,
   nights: [{date: '2022-07-24', status: 'booked'},
            {date: '2022-07-26', status: 'booked'}]
},
{
   id:2,
   nights: [{date: '2022-07-24', status: 'booked'},
            {date: '2022-07-25', status: 'booked'}
            {date: '2022-07-26', status: 'booked'}]
}
];


const array2 = [
{
   id:1,
   days: [{date: '2022-07-24', breakdown: []},
          {date: '2022-07-25', breakdown: []},
          {date: '2022-07-26', breakdown: []}]
},
{
   id:2,
   days: [{date: '2022-07-24', breakdown: [],
          {date: '2022-07-25', breakdown: [],
          {date: '2022-07-26', breakdown: []}]
}
];

const filteredArray2 = array2.flatMap(({ id, days}) => {
    const filterObject = array1.find((obj) => obj.id === id);
    return filterObject ? [{
      id,
      days: days.filter((day) => filterObject.nights.find(night => day.date === night.date)) 
    }] : [];
});

  • Related