Reputation: 10634
i am trying to figure out the best lodashy way to do some object iteration/mutation. I am trying to find all "sids" which have servers that have a role of "DB". expected result would be a variable which has the full props (tier, sidadm, sid, orasid, servers) of any SIDs which have servers which have role DB.
data
var landscape = [
{
"tier": "production",
"sidadm": "ptpadm",
"sid": "PTP",
"orasid": "oraptp",
"servers": [
{
"hostname": "testep00",
"roles": ["DB"]
},
{
"hostname": "testep01",
"roles": ["DG"]
},
{
"hostname": "testep02",
"roles": ["SAPMS"]
},
{
"hostname": "testep03",
"roles": ["SAPDI"]
},
{
"hostname": "testep04",
"roles": ["SAPDI"]
},
{
"hostname": "testep05",
"roles": ["SAPDI"]
},
{
"hostname": "testep06",
"roles": ["SAPDI"]
}
]
},
{
"tier": "techsandbox",
"sidadm": "bwzadm",
"sid": "BWZ",
"orasid": "orabwz",
"servers": [
{
"hostname": "testbw80",
"roles": ["DB"]
},
{
"hostname": "testbw81",
"roles": ["DG"]
},
{
"hostname": "testbw82",
"roles": ["SAPMS"]
},
{
"hostname": "testbw83",
"roles": ["SAPDI"]
}
]
},
{
"tier": "techsandbox",
"sidadm": "eczadm",
"sid": "ECZ",
"orasid": "oraecz",
"servers": [
{
"hostname": "testec81",
"roles": ["DG"]
},
{
"hostname": "testec82",
"roles": ["SAPDI", "SAPMS"]
}
]
}
];
This is what I have so far it works kinda, but doesn't exclude the SIDs which have empty server props. There has to be a better way of writing this with lodash, right?
// find me all SIDs with role "DB",
// should filter landscape and only return sids which have servers role=DB
// also should only contain the servers which are role=DB
var ls = _.extend({}, landscape);
_.each(ls, function (sid) {
var servers = _.filter(sid.servers, function (server) {
return _.contains(server.roles, 'DB');
});
// still need to strip out SID objects which have empty servers prop
sid.servers = servers;
});
console.log('sids1() ::', ls);
Upvotes: 0
Views: 51
Reputation: 816334
Just a simple filter
+ some
should suffice:
var result = landscape.filter(function(sid) {
return sid.servers.some(function(server) {
return server.roles.indexOf("DB") > -1;
});
});
Lodash provides implementations for both of these if you prefer it.
If you want to also only include servers with that specific role, you can map
and filter
:
var result = landscape
.map(function(sid) {
return Object.assign( // "clone" object
{},
sid,
{
servers: sid.servers.filter(function(server) {
return server.roles.indexOf("DB") > -1;
})
}
);
})
.filter(function(sid) {
return sid.servers.length > 0;
});
This can also be combined into a single reduce
or use a simple forEach
:
var result = [];
landscape.forEach(function(sid) {
var servers = sid.servers.filter(function(server) {
return server.roles.indexOf("DB") > -1;
});
if (servers.length > 0) {
result.push(Object.assign({}, side, {servers: servers});
}
});
Upvotes: 1