[openstack-dev] [heat][yaql] Deep merge map of lists?

Steven Hardy shardy at redhat.com
Mon Aug 29 06:25:27 UTC 2016


On Mon, Aug 29, 2016 at 07:07:09AM +0200, Thomas Herve wrote:
> On Sun, Aug 28, 2016 at 11:58 PM, Steven Hardy <shardy at redhat.com> wrote:
> > Hi all,
> >
> > I have a need to merge a list of maps of lists:
> >
> > heat_template_version: 2016-10-14
> >
> > outputs:
> >   debug:
> >     value:
> >       yaql:
> >         # dict(vms=>dict($.vms.select([$.name, $])))
> >         expression: dict($.data.l.select([$.keys().toList()[0],
> > $.values().toList()[0]]))
> >         data:
> >           l:
> >             - a: [123]
> >             - b: [123]
> >             - a: [456]
> >
> >
> >
> > I want to end up with debug as:
> >
> >   a: [123, 456]
> >   b: [123]
> >
> > Perhaps we need a map_deep_merge function, but can this be done with yaql?
> >
> > I suspect it can, but can't currently figure out how the assignment to the
> > intermediate "a" value is supposed to work, any ideas on the cleanest
> > approach appreciated!
> 
> I believe you don't need the intermediate value, and can rely on what
> you'd do in Python with setdefault:
> 
> dict($.groupBy($.keys().toList()[0], $.values().toList()[0][0]))
> 
> ought to work, I believe?

Indeed it does work, thanks!  groupBy is what I was missing :)

For anyone following, here's the updated template, and the output it
gives:

heat_template_version: 2016-10-14

outputs:
  debug:
    value:
      yaql:
        expression: dict($.data.l.groupBy($.keys().toList()[0],
$.values().toList()[0][0]))
        data:
          l:
            - a: [123]
            - b: [123]
            - a: [456]

[stack at instack ~]$ heat output-show foo debug
{
  "a": [
    123,
    456
  ], 
  "b": [
    123
  ]
}

Steve



More information about the OpenStack-dev mailing list