{% set arrayName = { 'key1':'value1', 'key2':'value2', 'key3':'value2' } %}
I can get the values with no problem, by calling the keys like:
{{ arrayName['key1'] }}
but could it be done the other way? I mean calling the value to get (array of) matching keys? I just run out of the keywords to search, and trial-n-error mode of my copy-paste programming didn’t work also
First, that’s not an array. That’s a dictionary. To be technical, arrays don’t exist in python unless you are using numpy. The 2 array-like objects are refered to as lists and tuples.
tuples and lists are collections of objects that can be accessed through indexing. Both are similar but lists have more functionalities than tuples. The big take away here is that everything is in order. Whatever you put in it will stay in that order.
dictionary is an object where you can access the items with an identifier instead of using an indexer. Also, there is no order for the objects. It would be like a bag of fruit. You go in and grab anything by name, like an apple.
{% set fruit = { 'apple':'value1', 'orange':'value2', 'grape':'value3' } %}
{{ fruit['apple'] }} #returns 'value1'
Now to answer your question:
It is not possible to get a list of items equal to your value. It would be possible with an extension, but that requires changes to HA. The best you can do is get the first item out.
{% set fruit = { 'apple':'value', 'orange':'value', 'grape':'value' } %}
{% set keys = fruit.keys() | list %}
{% set values = fruit.values() | list %}
{{ keys[values.index('value')] }} #returns apple
The drawback is that it will only return the first key equal to value, not all the values equal to value.
You might be able to do this, but it depends on what you ultimately want to do with the values. E.g., the following will find all the keys for elements whose value is “value2”:
{% for key,item in arrayName.items() if item=='value2' -%}
{% if not loop.first %},{% endif %}{{ key }}
{%- endfor %}
But being a Jinja template, it can only return a single string. So if you’re looking for a real “array” (i.e., list), then this can’t do it.
@petro - THANK YOU, once again for an educational-type of answer. I am using some tips’n’tricks that I learned from your earlier comments to my posts and they all work awesome. yeah, as you already know - I’m not a programmer or developer, but “touched” few languages, and my habits & naming comes straight from there. if something was similar to array from othe lang, I just called it array, forgive me! now I know more [and as of now - I already know I’ll use tuples & lists in some of my badly-written automations, just to pimp them up!]. and yes, I knew about returning the first key - tried to build some loops around it, but failed, and that’s why I wrote the post
@pnbruckner THANKS for the little loop too! just three lines, but already couple of things I need to check and understand correctly, so I would learn how to use it with consciousness, and not only copy+paste I guess that single string should be ok, I planned to use it in the loop to build entity_ids of booleans to be checked or switched [depends on automation]. should be enough!
you guys are awesome, if I could check two posts as solutions, that would be the best
Doesn’t that still just return a string that looks like a list??? If the end use is for specifying entity_id’s, most of those config options are specified as cv.entity_ids which wants a single string of entity_id’s separated by commas, so the extra brackets would break it.
It outputs a string with commas separating the items without brackets. Then the next line after the macro uses the macro and turns it into a list via split(’,’)
Yes, but it’s all one template, and the final result gets turned back into a string. E.g.:
script:
test:
sequence:
service: python_script.test
data_template:
input: >
{% set fruit = { 'apple':'value', 'orange':'value', 'grape':'blahblahblah' } %}
{% macro getkeys(mydict, myvalue) %}
{%- for key,item in mydict.items() if item==myvalue -%}
{%- if not loop.first %},{% endif %}{{ key }}
{%- endfor %}
{% endmacro %}
{{ getkeys(fruit, 'value').strip().split(',') }}
and python_scripts/test.py:
input = data.get('input')
logger.info('length of input is {}'.format(len(input)))
Results in:
2018-11-11 17:20:04 INFO (Thread-20) [homeassistant.components.python_script] Executing test.py: {'input': "['apple', 'orange']"}
2018-11-11 17:20:04 INFO (Thread-20) [homeassistant.components.python_script.test.py] length of input is 19
typing wasn’t possible, it had to be comma separated without list indicators or quotes. Also, please don’t revive old information threads. This was better left in the past. Thanks.