JSONNET获取数组中元素的位置

时间:2019-11-10 20:20:52

标签: for-loop jsonnet

我正在使用tstanisl's answer在Grafana中配置面板。我是第一次使用它,我非常喜欢它。但是,我很难理解某些方面。

我有类似以下内容:

.addTemplate(
  template.new(
    microservices,
    datasource='',
    query=std.join(',', std.map(function(x) x.text, service['microservices'])),
    label= services,
  )

我现在想要做的是在给定微服务的情况下获取它所占据的位置,以便能够将其分配给可变服务(然后通过 query = std获得我的自定义值)。 join(',',std.map(function(x)x.text,service ['microservices'])),)。

local services = std.extVar('services');
local service = services[x?];

变量服务具有以下形式:

[
  {
    // I'm trying to get this array position where my value is
    "key": "asd",
    "microservices": [
      {
        "key": "I HAVE THIS VALUE",
        "text": "ads"
      },
      {
        "key": "asd",
        "text": "ads"
      },
      {
        "key": "asd",
        "text": "asd"
      }
    ],
    "name": "bca",
    "services: [
      {
        "key": "bca",
        "name": "bca"
      }
    ]
  },
  {
    "key": "bca",
    "microservices": [
      {
        "key": "bca",
        "text": "bca"
      },
      {
        "key": "bca",
        "text": "bca"
      }
    ],
    "name": "bca",
    "services: [
      {
        "key": "bca",
        "name": "bca"
      }
    ]
  },
  {
    "key": "abc",
    "microservices": [
      {
        "key": "bca",
        "text": "bca"
      }
    ],
    "name": "abc",
    "services: [
      {
        "key": "ccc",
        "name": "ccc"
      }
    ]
  }
]

在任何其他语言中,这对我来说都是非常基本的操作。

var srv type
for x, service := range services{
  for _, microservice := range service.microservices{
    if microservice.key == "my value"{
      srv= services[x]
    }
}

有什么建议吗?

非常感谢您。

1 个答案:

答案 0 :(得分:1)

这也是Jsonnet中非常简单的操作。最自然的方法是使用数组推导,它也方便地支持过滤:

local service2 = [
    s for s in services
    if [ms for ms in s.microservices if ms.key == "I HAVE THIS VALUE"] != []
][0];

请注意,索引[0]-一般来说,可能有不止一项匹配服务,或者没有一项匹配服务。因此,如果您想获得第一个,则需要明确地接受它。

上面的代码是在假设您不关心实际索引的情况下编写的,您只想检索此服务。如果需要,它会变得稍微复杂一点:

local serviceIndex = [
  x for x in std.range(0, std.length(services) - 1)
  if [ms for ms in services[x].microservices if ms.key == "I HAVE THIS VALUE"] != []
][0];

顺便说一句,您可以使用std.filter之类的功能来达到相同的结果,但这会更加冗长。

BTW2我还将考虑提取函数hasMicroservice(service, msKey)以增强过滤的可读性。