合并对象时如何合并子数组的唯一值

问题描述 投票:0回答:1

我想将

.environments.default
.environments.dev
对象合并在一起,以便
dev
值覆盖任何
default
值,并且
default
值填充
dev
对象中未定义的任何内容。如果我使用
.environments.default * .environments.dev
,大多数对象都会正确合并,除了
env
secrets
对象下的数组列表。使用整个
dev
对象,但我希望数组列表与唯一值合并。

有没有办法用

jq
得到这个结果?如果有帮助,我也可以尝试在
yq
中使用 YAML 文件执行此操作。

我也很想知道这是否可以在代码中的任何地方不进行硬编码

"env"
"secrets"

当我在下面的源上使用

.environments.default * .environments.dev
时...

来源:

{
"environments": {
    "default": {
      "config": {
        "security": {
          "user": 0,
          "group": 0
        },
        "resources": {
          "limits": {
            "memory": "256Mi",
            "cpu": "500m"
          }
        },
        "env": [
          {
            "name": "DEFAULT_ENV",
            "value": "DEFAULT_ENV_VALUE"
          },
          {
            "name": "BASE_URL",
            "value": "DEFAULT_BASE_URL"
          }
        ],
        "secrets": [
          {
            "secretID": "567",
            "mountPath": "/default/dir/to/567/path"
          },
          {
            "secretID": "123",
            "mountPath": "/default/dir/to/123/path"
          },
          {
            "secretUUID": "789",
            "mountPath": "/default/dir/to/789/path"
          }
        ]
      }
    },
    "dev": {
      "config": {
        "replicas": 1,
        "resources": {
          "limits": {
            "cpu": "5000m"
          }
        },
        "env": [
          {
            "name": "BASE_URL",
            "value": "DEV_BASE_URL"
          },
          {
            "name": "DEV_ENV_1",
            "value": "DEV_ENV_1"
          }
        ],
        "secrets": [
          {
            "secretID": "456",
            "mountPath": "/dev/dir/to/456/path"
          },
          {
            "secretID": "123",
            "mountPath": "/dev/dir/to/456/path"
          }
        ]
      }
    }
  }
}

我明白了...

电流输出:

{
  "config": {
    "security": {
      "user": 0,
      "group": 0
    },
    "resources": {
      "limits": {
        "memory": "256Mi",
        "cpu": "5000m"
      }
    },
    "env": [
      {
        "name": "BASE_URL",
        "value": "DEV_BASE_URL"
      },
      {
        "name": "DEV_ENV_1",
        "value": "DEV_ENV_1"
      }
    ],
    "secrets": [
      {
        "secretID": "456",
        "mountPath": "/dev/dir/to/456/path"
      },
      {
        "secretID": "123",
        "mountPath": "/dev/dir/to/456/path"
      }
    ],
    "replicas": 1
  }
}

但我想要...

所需输出:

{
  "config": {
    "security": {
      "user": 0,
      "group": 0
    },
    "resources": {
      "limits": {
        "memory": "256Mi",
        "cpu": "5000m"
      }
    },
    "env": [
      {
        "name": "BASE_URL",
        "value": "DEV_BASE_URL"
      },
      {
        "name": "DEV_ENV_1",
        "value": "DEV_ENV_1"
      },
      {
        "name": "DEFAULT_ENV",
        "value": "DEFAULT_ENV_VALUE"
      }
    ],
    "secrets": [
      {
        "secretID": "456",
        "mountPath": "/dev/dir/to/456/path"
      },
      {
        "secretID": "123",
        "mountPath": "/dev/dir/to/456/path"
      },
      {
        "secretID": "567",
        "mountPath": "/default/dir/to/567/path"
      },
      {
        "secretUUID": "789",
        "mountPath": "/default/dir/to/789/path"
      }
    ],
    "replicas": 1
  }
}
jq yq
1个回答
0
投票

来自评论线程

env 列表的名称应该是唯一的,而 Secrets 列表的 SecretID 应该是唯一的。 [...]我想知道数组中的第一个对象键是否可以是唯一的? [...] 名称始终位于值之前,而 SecretID 始终位于 mountPath 之前

对象字段没有格式传达的顺序,只有数组项有。您在特定文件中观察到的顺序只是其当前的表示形式。

只是为了好玩,你会怎么做?

所以,让乐趣开始吧:

这将从

.default
分支捕获并迭代非空数组的所有项目(使用
paths(arrays | select(has(0)))
保存数组路径,使用
getpath(…)[]
保存每个项目的值,使用
to_entries[0]
保存第一个项目的键和值)。迭代的基础文档是您已经执行的合并,但这些数组从
.default
分支中删除,因此保存的项目可以单独测试并附加到它,如果它们通过了没有其他第一个键的值与它们匹配的条件:
 IN(.[][$v0.key]; $v0.value) | not

.environments | [.default | paths(arrays | select(has(0))) as $p
  | getpath($p)[] as $v | {$p,$v,v0:($v | to_entries[0])}
] as $a | reduce $a[] as {$p,$v,$v0} ((.default | delpaths([$a[].p])) * .dev;
  setpath($p; getpath($p) | . + [select(IN(.[][$v0.key]; $v0.value) | not) | $v])
)

演示

© www.soinside.com 2019 - 2024. All rights reserved.