2015-12-15 62 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