2015-12-15 39 views
0

我想弄清楚最好的方法来做一些对象迭代/变异。我试图找到具有“DB”角色的服务器的所有“sids”。预期的结果将是一个变量,它具有任何具有角色DB的服务器的SID的完整道具(层,sidadm,sid,orasid,服务器)。遍历对象数组,并过滤​​掉不匹配

数据

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"] 
     } 
    ] 
    } 
]; 

这是我迄今为止它还挺工作,但不排除具有空的服务器道具的SID。用lodash写出这个更好的方法,对吧?

// 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); 
+0

使用'reject' https://lodash.com/docs#reject – Edmund

回答

1

只是一个简单的filter + some应该足够了:

var result = landscape.filter(function(sid) { 
    return sid.servers.some(function(server) { 
    return server.roles.indexOf("DB") > -1; 
    }); 
}); 

Lodash为这两种提供实现,如果你喜欢它。

如果你想也只包含与特定角色的服务器,你可以mapfilter

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; 
    }); 

这也可以被组合成一个单一的reduce,或者使用一个简单的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}); 
    } 
}); 
+0

让我接近,但不排除服务器从sid prop没有角色:['DB']' – gorelative

+1

这不是很清楚从阙但我怀疑它。将更新我的答案。 –

+0

感谢有点难以解释它:) – gorelative