2015-12-15 3 views
0

Я пытаюсь найти лучший способ lodashy для выполнения итерации/мутации объектов. Я пытаюсь найти все «sids», у которых есть серверы, которые играют роль «DB». ожидаемым результатом будет переменная, которая имеет полный реквизит (уровень, sidadm, sid, orasid, servers) любых SID, у которых есть серверы, у которых есть роль DB.итерация по массиву объектов и фильтрация не соответствует

данные

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

Это то, что я до сих пор она работает своего рода, но не исключает SIDs, которые имеют пустой реквизит сервера. Должен быть лучший способ написать это с 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 обеспечивает реализацию для обоих из них, если вы предпочитаете.

Если вы хотите, чтобы также включать только серверы с этой конкретной роли, вы можете map и 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; 
    }); 

Это может также быть объединены в единый 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, которые не имеют' role: ['DB'] ' – gorelative

+1

Это было не очень понятно из очереди но я подозревал это. Обновит мой ответ. –

+0

спасибо, пожалуйста, трудно объяснить это :) – gorelative

Смежные вопросы