Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter dict keys based on their value #58699

Open
baby-gnu opened this issue Oct 9, 2020 · 1 comment
Open

Filter dict keys based on their value #58699

baby-gnu opened this issue Oct 9, 2020 · 1 comment
Labels
Feature new functionality including changes to functionality and code refactors, etc.
Milestone

Comments

@baby-gnu
Copy link

baby-gnu commented Oct 9, 2020

Is your feature request related to a problem? Please describe.

I find uselessly difficult to manipulate multi-level dict and think that some filters may ease their manipulation and make the SLS more readable.

I usually define a dict in pillar or some yaml data file and want to filter the keys based on subkeys values, for example:

bigdict:
  top1:
    enabled: true
    descr: this is a top level item1
  top2:
    enabled: false
    descr: this is a top level item2

I may want:

  • to get the key names of bigdict where enabled is true (or sometimes false)
  • to get the object where enabled is true (or sometimes false)

Describe the solution you'd like

Sometimes I want only the key names:

{%- set bigdict = {'top1': {'enabled': false, 'descr': 'this is a top level item1'},
                   'top2': {'enabled': true, 'descr': 'this is a top level item2'}} %}

The enabled tops are {{ bigdict | FilterKeysValues("enabled") | FilterThatReturnJustTheKeyName | join(", ") }}

Sometime, I may want a subkey value:

{%- set bigdict = {'top1': {'enabled': false, 'descr': 'this is a top level item1'},
                   'top2': {'enabled': true, 'descr': 'this is a top level item2'}} %}

The enabled tops descriptions are:
- {{ bigdict | FilterKeysValues("enabled") | FilterThatReturnAqueryLikeTraverse(":descr") | join("\n- ") }}

The FilterThatReturnJustTheKeyName and FilterThatReturnAqueryLikeTraverse may be the same FilterTraverseLike, as an idea:

  • FilterTraverseLike without any argument returns {'top1': {'enabled': false, 'descr': 'this is a top level item1'}}
  • FilterTraverseLike(".") returns the top1 string
  • FilterTraverseLike(":") returns {'enabled': false, 'descr': 'this is a top level item1'}
  • FilterTraverseLike(":descr") returns 'this is a top level item1'

The FilterKeysValues should obviously have a proper name and may have a parameter like the FilterTraverseLike:

{%- set bigdict = {'top1': {'value': {'enabled': false, 'descr': 'this is a top level item1'}},
                   'top2': {'value': {'enabled': true, 'descr': 'this is a top level item2'}}} %}

The enabled tops are {{ bigdict | FilterKeysValues(":value:enabled") | FilterThatReturnAqueryLikeTraverse(".") | join(", ") }}

Describe alternatives you've considered

Actually, I'm writing quite a bunch of jinja to do it, for example:

{%- set bigdict = {'top1': {'enabled': false, 'descr': 'this is a top level item1'},
                   'top2': {'enabled': true, 'descr': 'this is a top level item2'}} %}
{%- set filtered = [] %}
{%- for k, v in bigdict.items() %}
{%-   if v.get('enabled', False) %}
{%-     do filtered.append(k) %}
{%-   endif %}
{%- endfor %}
The enabled tops are {{ filtered | join(',') }}

or

{%- set bigdict = {'top1': {'enabled': false, 'descr': 'this is a top level item1'},
                   'top2': {'enabled': true, 'descr': 'this is a top level item2'}} %}
The enabled tops descriptions are:
{%- for k, v in bigdict.items() %}
{%-   if v.get('enabled', False) %}
- {{ v.descr }}
{%-   endif %}
{%- endfor %}

Additional context

@baby-gnu baby-gnu added the Feature new functionality including changes to functionality and code refactors, etc. label Oct 9, 2020
@baby-gnu
Copy link
Author

Instead of doing magic on first argument, the returned values could be configurable with parameters:

  • FilterTraverseLike without any argument returns {'top1': {'enabled': false, 'descr': 'this is a top level item1'}}
  • FilterTraverseLike(key=True) returns the top1 string
  • FilterTraverseLike(value=True) returns {'enabled': false, 'descr': 'this is a top level item1'}
  • FilterTraverseLike(traverse=":descr") returns 'this is a top level item1'
  • FilterTraverseLike(key=True, value=True) returns the tuple ('top1', {'enabled': false, 'descr': 'this is a top level item1'}) (this could be an implementation for Add a new jinja filter items #57970)
  • FilterTraverseLike(key=True, traverse=":descr") returns the tuple ('top1', 'this is a top level item1')

And as writing this comment I found useful to be able to do:

  • FilterTraverseLike(object=True) returns the object {_name: 'top1', 'enabled': false, 'descr': 'this is a top level item1'}

and this looks so promising to me that it could became a default behaviour ;-)

Regards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature new functionality including changes to functionality and code refactors, etc.
Projects
None yet
Development

No branches or pull requests

3 participants