arrays - 使用 .map (或另一个 stdlib 功能)创建哈希而不是数组

标签 arrays hash puppet hiera

我正在尝试以云中的 JMS 服务器为目标,puppet 模块 init.pp 需要向哈希添加一个 key 。

我正在读取 hiera block ,并且必须提取其中的一部分以形成新的哈希值。 .each 不返回任何值,因此我使用 .map。 我得到的值正是我想要的,但是当我尝试 deep_merge 时,我发现 .map 输出为数组。

服务.yaml

jms_subdeployment_instances:
   'BPMJMSModuleUDDs:BPMJMSSubDM':
      ensure:     'present'
      target:
       - 'BPMJMSServer_auto_1'
       - "BPMJMSServer_auto_%{::ec2_tag_name}"
      targettype:
        - 'JMSServer'
        - 'JMSServer'      

初始化.pp

  $jms_subdeployments = lookup('jms_subdeployment_instances', $default_params)
  $jms_target_args = $jms_subdeployments.map |$subdep, $value| {
    $jms_short_name = $subdep[0, 3]
    $jms_subdeployment_inst = $array_domain_jmsserver_addresses.map |$index, $server| {
      "${jms_short_name}JMSServer_auto_${server}"

      if defined('$jms_subdeployment_inst') {
        $jmsTargetArg = {
          "${subdep}" => {
            'target' => $jms_subdeployment_inst
          }
        }
      }
    }

  $merge_subdeployment_targets = merge($jms_subdeployments, $jms_target_args)



```Output
New JMS targets are : [{BPMJMSModuleUDDs:BPMJMSSubDM => {target => [BPMJMSServer_auto_server101, BPMJMSServer_auto_server102]}}]

封闭的 [ ] 给我带来了麻烦。据我所知,在 puppet .to_h 中也不起作用

谢谢

2019 年 7 月 22 日更新:

感谢您的回复,我不得不稍微调整它,因为 puppet 因“服务器错误:评估错误:评估方法调用时出错,‘值’参数‘hsh’需要哈希值,得到元组而失败”

  $array_domain_jmsserver_addresses = 
  any2array(hiera('pdb_domain_msserver_addresses'))
  $array_domain_jmsserver_addresses.sort()
  $jms_subdeployments = lookup('jms_subdeployment_instances', $default_params)
  $hash_domain_jmsserver_addresses = Hash($array_domain_jmsserver_addresses)

  if $hash_domain_jmsserver_addresses.length > 0 {
      $jms_target_arg_tuples = $jms_subdeployments.keys.map |$subdep| {
      $jms_short_name = $subdep[0, 3]
      $jms_subdeployment_inst = regsubst(
          $hash_domain_jmsserver_addresses.values, /^/, "${jms_short_name}JMSServer_auto_")

  # the (key, value) tuple to which this element maps
  [ $subdep, { 'target' => $jms_subdeployment_inst } ]
}

$jms_target_args = Hash($jms_target_arg_tuples)
} else {
$jms_target_args = {}
}

notify{"Normal array is : ${jms_subdeployments}": }
notify{"Second array is : ${jms_target_args}": }  

$merge_subdeployment_targets = deep_merge($jms_subdeployments, $jms_target_args)
notify{"Merged array is : ${merge_subdeployment_targets}": }

Normal is : {BPMJMSModuleUDDs:BPMJMSSubDM => {ensure => present, target => [BPMJMSServer_auto_1, BPMJMSServer_auto_server1], targettype => [JMSServer, JMSServer]},

Second is : {BPMJMSModuleUDDs:BPMJMSSubDM => {target => [BPMJMSServer_auto_server2]}

Merged is : {BPMJMSModuleUDDs:BPMJMSSubDM => {ensure => present, target => [BPMJMSServer_auto_server2], targettype => [JMSServer, JMSServer]}

期望的输出:

{BPMJMSModuleUDDs:BPMJMSSubDM => {ensure => present, target => [BPMJMSServer_auto_1, BPMJMSServer_auto_server1, BPMJMSServer_auto_server2], targettype => [JMSServer, JMSServer, JMSServer]}

最佳答案

when I tried a deep_merge I discovered that .map outputs as an array.

是的,这是its documented behaviormap() 应被视为集合元素上的函数,而不是整个集合上的函数,并且结果始终以数组形式提供。

查看 converting values to hashes 的替代方案可能会很有用。 。特别有吸引力的是这个:

  • An Array matching Array[Tuple[Any,Any], 1] is converted to a hash where each tuple describes a key/value entry

要利用此功能,请将每个条目映射到一个(键,值)元组,并将生成的元组数组转换为哈希值。您对该方法的尝试转换可能如下所示:

if $array_domain_jmsserver_addresses.length > 0 {
  $jms_target_arg_tuples = $jms_subdeployments.keys.map |$subdep| {
    $jms_short_name = $subdep[0, 3]
    $jms_subdeployment_inst = regsubst(
        $array_domain_jmsserver_addresses.sort, /^/, "${jms_short_name}JMSServer_auto_")

    # the (key, value) tuple to which this element maps
    [ $subdep, { 'target' => $jms_subdeployment_inst } ]
  }

  $jms_target_args = Hash($jms_target_arg_tuples)
} else {
  $jms_target_args = {}
}

$merge_subdeployment_targets = merge($jms_subdeployments, $jms_target_args)

请注意,由于您不使用 $jms_subdeployments 的值,因此我冒昧地通过应用 keys() 函数来稍微简化您的代码。我还使用 regsubst() 而不是 map()$array_domain_jmsserver_addresses 的元素形成目标名称,我个人认为更具可读性在这种情况下,特别是因为您没有使用索引。

我还推断出您的 if Defined() 测试要完成的意思,并将其替换为 $array_domain_jmsserver_addresses 长度的最外层测试大批。人们还可以以更函数式的形式编写它,通过构建哈希而不考虑是否有任何目标,然后对其进行过滤,但这似乎很浪费,因为看起来要么全部条目将具有(相同的)目标,或者没有。

关于arrays - 使用 .map (或另一个 stdlib 功能)创建哈希而不是数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57114636/

相关文章:

c++ - 覆盖子类中的数组大小

javascript - 获取 hashchange 之前的哈希值

java - 为什么我的哈希表不能在更大的范围内工作?

centos - 在 puppet 中调试失败 'boost::locale::conv::invalid_charset_error'

puppet - Puppet 中使用箭头的包含类和链接类之间的区别

c - 使用C在排序数组中大于给定数字的最小数字的数组索引

python - n维数组中唯一值的索引

arrays - 在 New Swift 中对二维数组进行排序,之前的排序不起作用

hash - 有效的 md5/sha1/etc 输入字符?

macos - 从boxen卸载nodenv