是否有一种简单的方法来获取对象图中第二级的键值?

时间:2019-01-11 23:45:50

标签: javascript node.js dictionary multi-level

我正在编写一些Node.js,以基于YAML模板部署AWS CloudFormation堆栈,希望使所有模板通用一个脚本,因此希望解析YAML以检测某些功能,因为这会影响API调用。我有一种方法可以将YAML转换回JSON,然后...

出于这个示例的目的,我想知道是否有任何IAM资源(类型如“ AWS :: IAM :: Role”,“ AWS :: IAM :: Group”),以及这些资源中是否有显式名称。我必须为一个未命名的IAM资源指定功能CAPABILITY_IAM,但是如果有名称,则需要使用CAPABILITY_NAMED_IAM。

当它是对象数组时,我已经使用.map()和.filter()完成了此操作,但是这种格式是对象映射,因此无法使用。我似乎找不到找到类似方法的简单“单线”方法-也许我不知道正确的搜索词?

因此,对于此输入(经过编辑以减少):

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "UnnamedRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "Path": "/"
      }
    },
    "NamedRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "RoleName": "SomeName"
        "Path": "/"
      }
    },
    "IrrelevantNonIAMResource": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "FunctionName": "SomeFunction"
      }
    }
  }
}

所以,第一个问题-希望获得此输出:

  "Resources": {
    "UnnamedRole": {
      "Type": "AWS::IAM::Role",
      "Needs": "CAPABILITY_IAM"
    },
    "NamedRole": {
      "Type": "AWS::IAM::Role",
      "Needs": "CAPABILITY_NAMED_IAM"
    }
  }

额外的信用!! -只需一个字就能回答:

  • NONE =找不到需要功能的IAM资源
  • CAPABILITY_IAM =至少找到一个没有名称的IAM
  • CAPABILITY_NAMED_IAM =找到至少一个IAM,名称为-

@James要求输入代码-我对此没有任何要求,为什么我在这里。但是,我想得到一种看起来更接近这种风格的东西-我用来在Route53中找到相关域的地方,其中HostedZones是对象数组。上面的资源是一个对象图:

let zones = data.HostedZones.filter(z => z.Config.PrivateZone == false)
                            .map(z => ({ Id: z.Id.replace('/hostedzone/',''), Name: z.Name}))
                            .filter(z => z.Name.includes(domainName));

是否有类似的短语法可以在一排长行中完成我想做的事情?

关于涵盖本主题的任何很好的参考。 Node的新手-在2小时的搜索中找不到任何内容。

2 个答案:

答案 0 :(得分:0)

好吧,似乎没有doing what you ask的本机方式,因此请像单行语句那样去做,但是(如链接答案中所述)您可以编写自己的objectMap函数。 / p>

另一方面,您可以使用一些实用程序库,例如lodash,这些实用程序库将使用它们的.chain .map个可以迭代对象的函数。

希望这对您有所帮助!

答案 1 :(得分:0)

可以使用reduce函数来完成操作(顺便说一句,您在"RoleName": "SomeName"这行有错误,应该以{{1​​}}结尾)。

,

Object.keys(o.Resources).reduce((acc, v) => {
  if (o.Resources[v].Type === "AWS::IAM::Role" && o.Resources[v].Properties.RoleName) {
    acc.Resources[v] = { Type: "AWS::IAM::Role", Needs: "CAPABILITY_NAMED_IAM"}
  } else if (o.Resources[v].Type === "AWS::IAM::Role") {
    acc.Resources[v] = { Type: "AWS::IAM::Role", Needs: "CAPABILITY_IAM" }
  }
  return acc;
}, { Resources: {}});