-1

I have data with the following structure:

var DATA = {
'device_groups': [{
  'id': '1',
  'name': 'group 1',
  'devices': [{
    'id': 11,
    'name': 'device 11',
    'active': 1
  }, {
    'id': 12,
    'name': 'device 12',
    'active': 0
  }, {
    'id': 13,
    'name': 'device 13',
    'active': 0
  }] 
}, {
  'id': '2',
  'name': 'group 2',
  'devices': [{
    'id': 21,
    'name': 'device 21',
    'active': 1
  }, {
    'id': 22,
    'name': 'device 22',
    'active': 0
  }, {
    'id': 23,
    'name': 'device 23',
    'active': 1
  }]
}, {
  'id': '3',
  'name': 'group 3',
  'devices': [{
    'id': 31,
    'name': 'device 31',
    'active': 1
  }, {
    'id': 32,
    'name': 'device 32',
    'active': 0
  }, {
    'id': 33,
    'name': 'device 33',
    'active': 1
  }]  
}]
};

From all these "device_groups" arrays and inner "devices" arrays I need to get a single array of objects where 'active' is true (1).

How to do it the ES6+ way?

Igal
  • 5,833
  • 20
  • 74
  • 132
  • 1
    What have you tried so far? – Andreas Jan 22 '19 at 17:11
  • @Andreas Tried to use map and filter, but got lost somewhere in the middle. Tried to do it step by step but somehow got an array of arrays... – Igal Jan 22 '19 at 17:18
  • 2
    Then please add your approach and we will help you to fix it. SO is not a "I need ... Please give me a solution" service. – Andreas Jan 22 '19 at 17:20

5 Answers5

1

You can use map and filter like this:

var DATA={'device_groups':[{'id':'1','name':'group 1','devices':[{'id':11,'name':'device 11','active':1},{'id':12,'name':'device 12','active':0},{'id':13,'name':'device 13','active':0}]},{'id':'2','name':'group 2','devices':[{'id':21,'name':'device 21','active':1},{'id':22,'name':'device 22','active':0},{'id':23,'name':'device 23','active':1}]},{'id':'3','name':'group 3','devices':[{'id':31,'name':'device 31','active':1},{'id':32,'name':'device 32','active':0},{'id':33,'name':'device 33','active':1}]}]}

const filtered = DATA.device_groups.map(a => a.devices.filter(a => a.active === 1)),
  output = [].concat(...filtered);

console.log(output)

Or using a simple reduce

var DATA={'device_groups':[{'id':'1','name':'group 1','devices':[{'id':11,'name':'device 11','active':1},{'id':12,'name':'device 12','active':0},{'id':13,'name':'device 13','active':0}]},{'id':'2','name':'group 2','devices':[{'id':21,'name':'device 21','active':1},{'id':22,'name':'device 22','active':0},{'id':23,'name':'device 23','active':1}]},{'id':'3','name':'group 3','devices':[{'id':31,'name':'device 31','active':1},{'id':32,'name':'device 32','active':0},{'id':33,'name':'device 33','active':1}]}]}

const devices = DATA.device_groups
                  .reduce((a,d) => a.concat(d.devices.filter(f => f.active)),[]);

console.log(devices)
adiga
  • 34,372
  • 9
  • 61
  • 83
  • Thanks! Looks like what I needed and waaay more efficient than what I tried to do... – Igal Jan 22 '19 at 17:34
0

You can do it using reduce and filter.

By filter we take out only the elements from devices which are having status active and than we concat them in final output

var DATA={'device_groups':[{'id':'1','name':'group 1','devices':[{'id':11,'name':'device 11','active':1},{'id':12,'name':'device 12','active':0},{'id':13,'name':'device 13','active':0}]},{'id':'2','name':'group 2','devices':[{'id':21,'name':'device 21','active':1},{'id':22,'name':'device 22','active':0},{'id':23,'name':'device 23','active':1}]},{'id':'3','name':'group 3','devices':[{'id':31,'name':'device 31','active':1},{'id':32,'name':'device 32','active':0},{'id':33,'name':'device 33','active':1}]}]}

let output = DATA.device_groups.reduce((op,cur)=>{
  let temp = cur.devices.filter(ele=> ele.active)
  op = op.concat(temp)
  return op;
},[])

console.log(output)
Code Maniac
  • 37,143
  • 5
  • 39
  • 60
0

basically you can use reduce and filter to achieve what you want

var DATA = {
  'device_groups': [{
    'id': '1',
    'name': 'group 1',
    'devices': [{
      'id': 11,
      'name': 'device 11',
      'active': 1
    }, {
      'id': 12,
      'name': 'device 12',
      'active': 0
    }, {
      'id': 13,
      'name': 'device 13',
      'active': 0
    }]
  }, {
    'id': '2',
    'name': 'group 2',
    'devices': [{
      'id': 21,
      'name': 'device 21',
      'active': 1
    }, {
      'id': 22,
      'name': 'device 22',
      'active': 0
    }, {
      'id': 23,
      'name': 'device 23',
      'active': 1
    }]
  }, {
    'id': '3',
    'name': 'group 3',
    'devices': [{
      'id': 31,
      'name': 'device 31',
      'active': 1
    }, {
      'id': 32,
      'name': 'device 32',
      'active': 0
    }, {
      'id': 33,
      'name': 'device 33',
      'active': 1
    }]
  }]
};
const deviceGroups = DATA.device_groups;

const solution = deviceGroups.reduce((result, devicegroup) => {
  const filteredDevices = devicegroup.devices.filter(device => device.active === 1)
  return [...result, ...filteredDevices]
}, [])

console.log(solution)
Prince Hernandez
  • 3,623
  • 1
  • 10
  • 19
0

Using reduce merge the inner array of devices from every device_groups into one array of devices. Then filter the merged array with active === 1 to get one single array of devices which are active.

var DATA = {"device_groups":[{"id":"1","name":"group 1","devices":[{"id":11,"name":"device 11","active":1},{"id":12,"name":"device 12","active":0},{"id":13,"name":"device 13","active":0}]},{"id":"2","name":"group 2","devices":[{"id":21,"name":"device 21","active":1},{"id":22,"name":"device 22","active":0},{"id":23,"name":"device 23","active":1}]},{"id":"3","name":"group 3","devices":[{"id":31,"name":"device 31","active":1},{"id":32,"name":"device 32","active":0},{"id":33,"name":"device 33","active":1}]}]};

var devices = DATA.device_groups
                  .reduce((acc, ele) => {
                     acc = acc.concat([...ele['devices']]); //merging each device array with the next with the concat().
                     return acc;
                   },[])
                  .filter((data) => data['active'] === 1);
console.log(devices);
Fullstack Guy
  • 16,368
  • 3
  • 29
  • 44
0

you can use just forEach and spread ... operator and push filtered results where active property is true, in final array

var DATA = {'device_groups': [{'id': '1','name': 'group 1','devices': [{'id': 11,'name': 'device 11','active': 1}, {'id': 12,'name': 'device 12','active': 0}, {'id': 13,'name': 'device 13','active': 0}] }, {'id': '2','name': 'group 2','devices': [{'id': 21,'name': 'device 21','active': 1}, {'id': 22,'name': 'device 22','active': 0}, {'id': 23,'name': 'device 23','active': 1
  }]}, {'id': '3','name': 'group 3','devices': [{'id': 31,'name': 'device 31','active': 1}, {'id': 32,'name': 'device 32','active': 0}, {'id': 33,'name': 'device 33','active': 1}]}]};

const result =[];
DATA.device_groups.forEach(devGroup => result.push(...devGroup.devices.filter(d => d.active)));
console.log(result);
Artyom Amiryan
  • 2,846
  • 1
  • 10
  • 22