我有一个数组如下:
$servers = [
{name => 'server1', address => '10.10.10.11', port => 8081},
{name => 'server2', address => '10.10.10.12', port => 8082},
]
我需要以编程方式将其转换为基于'name'键的哈希:
$serversMap = {
server1 => {address => '10.10.10.11', port => 8081},
server2 => {address => '10.10.10.12', port => 8082},
}
这适用于傀儡3:
$serversMap = $servers.reduce({}) |$cumulate, $server| {
$key = "${server['name']}"
$value = $server.filter |$entry| { $entry[0] != 'name' }
$tmp = merge($cumulate, {"$key" => $value })
$tmp
}
然而,有更简单的方法吗?
为什么我需要创建时态变量$ tmp?
没有它,我得到Error: Function 'merge' must be the value of a statement
错误。
ps:很明显,但无论如何我会说:$ servers变量是给我的,我不能改变它的结构。我需要相同的数据,但需要$ serversMap的形式。所以,我问如何以编程方式从$ servers转换为$ serversMap。
答案 0 :(得分:4)
除了$ tmp变量,此代码是最佳的。
$ tmp变量需要存在,因为合并函数是rvalue
。来自docs:
实际上有两种完全不同的函数类型 - rvalues(返回值)和语句(不是)。如果您正在编写右值函数,则必须传递:type => :创建函数时的右值;见下面的例子。
当涉及到rvalue语句时,产生此错误的puppet源是非常自我解释的:
# It is harmless to produce an ignored rvalue, the alternative is to mark functions
# as appropriate for both rvalue and statements
# Keeping the old behavior when a pblock is not present. This since it is not known
# if the lambda contains a statement or not (at least not without a costly search).
# The purpose of the check is to protect a user for producing a meaningless rvalue where the
# operation has no side effects.
#
if !pblock && Puppet::Parser::Functions.rvalue?(@name)
raise Puppet::ParseError,
"Function '#{@name}' must be the value of a statement"
end
真正的原因是Puppet并不像语言那么复杂。如果你想要真正的电源切换到Ruby。