想在一行代码中从 split() 分配多个变量
Would like to assign multiple variables from split() on one line of code
给定以下数组:
// use strings only in the form <protocol>-<port>
ports: [
'tcp-1514',
'tcp-8080',
'tcp-8443',
],
我正在尝试编写 jsonnet 来拆分数组的每个元素以生成此对象(在此处以 yaml 表示):
ports:
- name: "tcp-1514"
containerPort: 1514
protocol: "tcp"
- name: "tcp-8080"
containerPort: 8080
protocol: "tcp"
- name: "tcp-8443"
containerPort: 8443
protocol: "tcp"
我已经尝试了几次数组理解迭代来做到这一点,请注意我是 jsonnet 的新手。最新的迭代是这样的:
ports: [
{
local proto, port ::= std.split(port_obj, '-');
name: port_obj,
containerPort: port,
protocol: proto,
} for port_obj in $.sharedConfig.ports,
]
其中 $.sharedConfig.ports
是端口分配。问题是local proto, port ::= std.split(port_obj, '-');
。我不确定这是有效代码。解释器正在对它进行 poopooing,我找不到任何示例或文档表明这是有效的。
最终,如果它无效,那么我将不得不 split() 两次,但那将是不幸的。例如,这有效:
{
local ports = ['tcp-1514', 'tcp-8080', 'tcp-8443',],
ports: [
local port = std.split(name,'-')[1];
local proto = std.split(name,'-')[0];
{
name: name,
protocol: proto,
containerPort: port,
}
for name in ports],
}
产生:
{
"ports": [
{
"containerPort": "1514",
"name": "tcp-1514",
"protocol": "tcp"
},
{
"containerPort": "8080",
"name": "tcp-8080",
"protocol": "tcp"
},
{
"containerPort": "8443",
"name": "tcp-8443",
"protocol": "tcp"
}
]
}
和 YAML:
---
ports:
- containerPort: '1514'
name: tcp-1514
protocol: tcp
- containerPort: '8080'
name: tcp-8080
protocol: tcp
- containerPort: '8443'
name: tcp-8443
protocol: tcp
...但我真的不喜欢两行变量赋值。我测试得越多,我就越相信我确定单行赋值是不可行的。
谁能告诉我我错在哪里,我将不胜感激。
它可能看起来像一个简单的答案(您可能已经考虑过),但它是这样的:使用一个本地变量来保存 split()
结果,然后在字段的赋值中引用它->
简单回答:
{
local ports = ['tcp-1514', 'tcp-8080', 'tcp-8443'],
ports: [
local name_split = std.split(name, '-');
{
name: name,
protocol: name_split[0],
containerPort: name_split[1],
}
for name in ports
],
}
混淆的答案(没有临时本地 w/split() 结果):
// Return a map from zipping arr0 (keys) and arr1 (values)
local zipArrays(arr0, arr1) = std.foldl(
// Merge each (per-field) object into a single obj
function(x, y) x + y,
// create per-field object, e.g. { name: <name> },
std.mapWithIndex(function(i, x) { [arr0[i]]: x }, arr1),
{},
);
{
local ports = ['tcp-1514', 'tcp-8080', 'tcp-8443'],
// Carefully ordered set of fields to "match" against: [name] + std.split(...)
local vars = ['name', 'protocol', 'containerPort'],
ports: [
zipArrays(vars, [name] + std.split(name, '-'))
for name in ports
],
}
给定以下数组:
// use strings only in the form <protocol>-<port>
ports: [
'tcp-1514',
'tcp-8080',
'tcp-8443',
],
我正在尝试编写 jsonnet 来拆分数组的每个元素以生成此对象(在此处以 yaml 表示):
ports:
- name: "tcp-1514"
containerPort: 1514
protocol: "tcp"
- name: "tcp-8080"
containerPort: 8080
protocol: "tcp"
- name: "tcp-8443"
containerPort: 8443
protocol: "tcp"
我已经尝试了几次数组理解迭代来做到这一点,请注意我是 jsonnet 的新手。最新的迭代是这样的:
ports: [
{
local proto, port ::= std.split(port_obj, '-');
name: port_obj,
containerPort: port,
protocol: proto,
} for port_obj in $.sharedConfig.ports,
]
其中 $.sharedConfig.ports
是端口分配。问题是local proto, port ::= std.split(port_obj, '-');
。我不确定这是有效代码。解释器正在对它进行 poopooing,我找不到任何示例或文档表明这是有效的。
最终,如果它无效,那么我将不得不 split() 两次,但那将是不幸的。例如,这有效:
{
local ports = ['tcp-1514', 'tcp-8080', 'tcp-8443',],
ports: [
local port = std.split(name,'-')[1];
local proto = std.split(name,'-')[0];
{
name: name,
protocol: proto,
containerPort: port,
}
for name in ports],
}
产生:
{
"ports": [
{
"containerPort": "1514",
"name": "tcp-1514",
"protocol": "tcp"
},
{
"containerPort": "8080",
"name": "tcp-8080",
"protocol": "tcp"
},
{
"containerPort": "8443",
"name": "tcp-8443",
"protocol": "tcp"
}
]
}
和 YAML:
---
ports:
- containerPort: '1514'
name: tcp-1514
protocol: tcp
- containerPort: '8080'
name: tcp-8080
protocol: tcp
- containerPort: '8443'
name: tcp-8443
protocol: tcp
...但我真的不喜欢两行变量赋值。我测试得越多,我就越相信我确定单行赋值是不可行的。
谁能告诉我我错在哪里,我将不胜感激。
它可能看起来像一个简单的答案(您可能已经考虑过),但它是这样的:使用一个本地变量来保存 split()
结果,然后在字段的赋值中引用它->
简单回答:
{
local ports = ['tcp-1514', 'tcp-8080', 'tcp-8443'],
ports: [
local name_split = std.split(name, '-');
{
name: name,
protocol: name_split[0],
containerPort: name_split[1],
}
for name in ports
],
}
混淆的答案(没有临时本地 w/split() 结果):
// Return a map from zipping arr0 (keys) and arr1 (values)
local zipArrays(arr0, arr1) = std.foldl(
// Merge each (per-field) object into a single obj
function(x, y) x + y,
// create per-field object, e.g. { name: <name> },
std.mapWithIndex(function(i, x) { [arr0[i]]: x }, arr1),
{},
);
{
local ports = ['tcp-1514', 'tcp-8080', 'tcp-8443'],
// Carefully ordered set of fields to "match" against: [name] + std.split(...)
local vars = ['name', 'protocol', 'containerPort'],
ports: [
zipArrays(vars, [name] + std.split(name, '-'))
for name in ports
],
}