gpt4 book ai didi

node.js - json 键替换为覆盖部分

转载 作者:太空宇宙 更新时间:2023-11-03 23:16:14 24 4
gpt4 key购买 nike

我有一个配置 json 文件,这是一个示例

{
"version": "1.0",
"producer": {
"name": "app_name_{{ ENVIRONMENT }}_producer",
"kms_key_alias": "alias/app_name_{{ ENVIRONMENT }}_producer_key",
"shards": 1,
"subscriptions": [
{
"name": "app_name1_{{ ENVIRONMENT }}_consumer",
"account_id": "123456789012",
"active": true
},
{
"name": "app_name2_{{ ENVIRONMENT }}_consumer",
"account_id": "987654321098",
"active": true
}
]
},
"consumers": [
{
"name": "app_name_{{ ENVIRONMENT }}_consumer",
"kms_key_alias": "alias/app_name_{{ ENVIRONMENT }}_consumer_key",
"shards": 1
}
],
"overrides": {
"prod": {
"producer": {
"shards": 2,
"subscriptions": [
{
"name": "app_name1_{{ ENVIRONMENT }}_consumer",
"account_id": "123456789012",
"active": false
}
]
},
"consumers": [
{
"name": "app_name_{{ ENVIRONMENT }}_consumer",
"shards": 3
}
]
}
}
}

我的目标是为该环境生成最终配置。环境是一个变量。

prod 的配置将有所不同。比如 prod 中的 Producer.shards 将会是 2,而不是 1。

流程是,读取json文件,生产者和消费者的一部分,保存到一个新变量new_json中。这可以理解为默认值。

{
"producer": {
...
}
consumers": {
...
}
}

然后读取覆盖的session,如果环境是prod,则会覆盖相关key中的值。

我编写了forEach代码来读取overrides中的每个键,然后我需要确认该键是列表还是映射,然后转到该部分的末尾,替换new_json中的相同键。

const json = JSON.parse(template)

if ({}.hasOwnProperty.call(overrides, environment)) {
const env = overrides[environment];

Object.keys(env).forEach((key){
...
}
}

示例 json 很简单。真正的json有几百行。因此遍历每个键并不是有效的方法。

是否有任何快速/智能的方法可以直接将覆盖中的任何键覆盖到 new_json

更新#1

使用 Object.assign() ,我仍然需要检查每个键,否则,我得到的键会更少。

例如,使用下面的代码,我在订阅列表中获得的信息较少。

$ cat a.js
const fs = require('fs');
const swig = require('swig-templates');

const environment='prod';

let template = swig.compileFile("jsoncontent.json");

template = template({
ENVIRONMENT: environment,
});

const json = JSON.parse(template);

Object.assign(json.producer, json.overrides.prod.producer)
delete json.overrides

console.log(JSON.stringify(json, null, 2));

$ node a.js
{
"version": "1.0",
"producer": {
"name": "app_name_prod_producer",
"kms_key_alias": "alias/app_name_prod_producer_key",
"shards": 2,
"subscriptions": [
{
"name": "app_name1_prod_consumer",
"account_id": "123456789012",
"active": false
}
]
},
"consumers": [
{
"name": "app_name_prod_consumer",
"kms_key_alias": "alias/app_name_prod_consumer_key",
"shards": 1
}
]
}

更新#2

感谢指出 lodash.defaultsDeep ,但是当合并列表中的 map 时,它必须在同一位置一对一匹配。

使用exist作为示例,如果我稍微调整overrides,订阅的第一个列表,名称会从app_name1更改为app_name2

"overrides": {
"prod": {
"producer": {
"shards": 2,
"subscriptions": [
{
"name": "app_name2_{{ ENVIRONMENT }}_consumer",
"account_id": "123456789012",
"active": false
}
]
}
}

结果将是:

{ shards: 2,
subscriptions:
[ { name: 'app_name2_prod_consumer',
account_id: '123456789012',
active: false },
{ name: 'app_name2_prod_consumer',
account_id: '987654321098',
active: true } ],
name: 'app_name_prod_producer',
kms_key_alias: 'alias/app_name_prod_producer_key' }

现在有两个 app_name2

最佳答案

Object.assign似乎正是您所需要的。

示例:

var o1 = {
a: 1,
b: 2
}

var override = {
a: 9
}

Object.assign(o1, override)
console.log(o1) // {a: 9, b: 2}

编辑

Object.assign 仅循环遍历根级别。
对于深度赋值,您可以使用 lodash.defaultsDeep :

var env = _.defaultsDeep(json.overrides.prod.producer, json.producer)

关于node.js - json 键替换为覆盖部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55154811/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com