迭代对象数组并过滤掉不匹配的对象

时间:2015-12-15 16:49:13

标签: javascript lodash

我试图找出做一些对象迭代/变异的最佳方法。我想找到所有的" sids"其服务器具有" DB"的作用。预期结果将是一个变量,它具有任何具有角色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);

1 个答案:

答案 0 :(得分: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});
  }
});
相关问题