Dorian Gaensslen
Dorian Gaensslen

Reputation: 303

Puppet: Merge a Hash with same keys

I have an array

$servers = [192.168.1.1, 192.168.1.2]

Which should be converted into a Array with hashes of the following form (an array with hashes and as the key "hostname" and the actual value of the array servers):

[
    { hostname => 192.168.1.1 }
    { hostname => 192.168.1.2 }
]

I tried the following:

$servers_hash = $servers.reduce({}) |$servermerge, $serverip| {
  $servermerge + { 'hostname' => $serverip }
}

The problem with this is, that if two hashes who have the same key are merged with the + , the first one gets overwritten. So only { hostname => 192.168.1.2 } is left.

Update: and the following:

$servers_array = $servers.reduce([]) |$servermerge, $serverip| {
  $servermerge + { 'hostname' => $serverip }
}

Which gives: [[hostname, 192.168.1.1], [hostname, 192.168.1.2]]

Upvotes: 0

Views: 1017

Answers (2)

Henrik Lindberg
Henrik Lindberg

Reputation: 1106

Since you want as many results as there are entries in the input the easiest (and best) is to use the map() function:

$servers_array = $servers.map |$ip| { { 'hostname' => $ip } }

While the general form for iteration that produces a new value is reduce() it is slightly more complicated as you have to construct the resulting array. When doing so in puppet, each append with << operator creates a new copy of the array. If the input array is long this can become a significant overhead. For that reason, the more specialized map(), filter() etc. iterative functions should be preferred over reduce() when it is possible to do so since those function hold a temporary mutable state when they build up the result.

Upvotes: 2

Dorian Gaensslen
Dorian Gaensslen

Reputation: 303

Solution:

If a + is used, the righthand side of the code is casted to an array, needles what it was before. With the << this casting isn't done.

$servers_array = $servers.reduce([]) |$servermerge, $serverip| {
  $servermerge << { 'hostname' => $serverip }
}

Which gives: [{hostname, 192.168.1.1}, {hostname, 192.168.1.2}]

Upvotes: 0

Related Questions