Home > OS >  How to filter with an array inside array object
How to filter with an array inside array object

Time:09-28

Here's the data:

userRoom = ['rm1'];

    data = [{
      name: 'building 1',
      building: [{
       room: 'rm1',
       name: 'Room 1'
      },{
       room: 'rm2',
       name: 'Room 2'
      }]
     },{
      name: 'building 2',
      building: [{
       room: 'rm3',
       name: 'Room 3'
      }]
     },{
      name: 'building 3',
      building: [{
       room: 'rm1',
       name: 'Room 1'
      }]
     }]

What I'm trying to do here is to display the data which it has a building room1 and filter it.

expected output will be like this:

 [{
      name: 'building 1',
      building: [{
       room: 'rm1',
       name: 'Room 1'
      },{
       room: 'rm2',
       name: 'Room 2'
      }]
     },{
      name: 'building 3',
      building: [{
       room: 'rm1',
       name: 'Room 1'
      }]
     }]

What I did is

data.map(x => x['building'].filter(y=> userRoom.includes(y.room));

but it doesn't work.

CodePudding user response:

As I mentioned in my comment, use filter > some > includes for the cleanest solution:

userRoom = ['rm1'];

data = [{
  name: 'building 1',
  building: [
    { room: 'rm1', name: 'Room 1' },
    { room: 'rm2', name: 'Room 2' }
  ]
}, {
  name: 'building 2',
  building: [
    { room: 'rm3', name: 'Room 3' }
  ]
}, {
  name: 'building 3',
  building: [
    { room: 'rm1', name: 'Room 1' }
  ]
}];

let filtered = data.filter(i => 
  i.building.some(j => 
    userRoom.includes(j.room)));

console.log(filtered);

To elaborate on why this works:

  • You want to filter the data array, as you want so select which of the entries in there you do and don't want to have returned.
  • To determine which building passes the test required for the filter, some of the rooms in that building need to match a rule...
  • This rule is that the room's identifier has to be included in the userRoom array, hence the use of includes.

CodePudding user response:

This cant be done with Array.map, because, Array.map always returns a node against each node of the input array. Try making use of any other looping logic.

Array.filter with Array.some will do the trick

const userRoom = ['rm1'];
const data = [{"name":"building 1","building":[{"room":"rm1","name":"Room 1"},{"room":"rm2","name":"Room 2"}]},{"name":"building 2","building":[{"room":"rm3","name":"Room 3"}]},{"name":"building 3","building":[{"room":"rm1","name":"Room 1"}]}];
const output = data.filter((curr) => curr['building'].some(y=> userRoom.includes(y.room)));
console.log(output);

What you have to do is filter the data array with some condition.

Your condition is true, so use that with Array.some. Filter the data with this condition.

CodePudding user response:

Using some, filter and includes

const data = [{"name":"building 1","building":[{"room":"rm1","name":"Room 1"},{"room":"rm2","name":"Room 2"}]},{"name":"building 2","building":[{"room":"rm3","name":"Room 3"}]},{"name":"building 3","building":[{"room":"rm1","name":"Room 1"}]}];

const anyUserRoomInBuilding = 
(building, userRoom) => building.some(({room}) => userRoom.includes(room));

const getBuildingsByUserRoom = 
(data, userRoom) => data.filter(({building}) => anyUserRoomInBuilding(building, userRoom))

console.log(getBuildingsByUserRoom(data, ['rm1']));

// console.log(getBuildingsByUserRoom(data, ['rm3', 'rm1']));
.as-console-wrapper { max-height: 100% !important; top: 0 }

CodePudding user response:

let filtered = data.filter(i => {
  return i.building.filter(j => {
    return userRoom.includes(j.room);
  }).length > 0;
});

userRoom = ['rm1'];

data = [{
  name: 'building 1',
  building: [{
    room: 'rm1',
    name: 'Room 1'
  }, {
    room: 'rm2',
    name: 'Room 2'
  }]
}, {
  name: 'building 2',
  building: [{
    room: 'rm3',
    name: 'Room 3'
  }]
}, {
  name: 'building 3',
  building: [{
    room: 'rm1',
    name: 'Room 1'
  }]
}]

let filtered = data.filter(i => {
  return i.building.filter(j => {
    return userRoom.includes(j.room);
  }).length > 0;
});

console.log(filtered);

  • Related