In home assistant jinja code, it seems that it is possible to apply multiplication to each element of an array using the map function:
{% set numbers = [2, 4, 6, 8] %}
{{ numbers | map('multiply', 2) | list }}
The output of this statement is:
[
4,
8,
12,
16
]
Now it would seem logical that you could do the same for the other maths functions too such as divide, eg.:
{% set numbers = [2, 4, 6, 8] %}
{{ numbers | map('divide', 2) | list }}
but this fails with the error:
TemplateRuntimeError: No filter named ‘divide’
This seems to be the case for divide, add and minus, with only multiply working. Why only support one function?
I get that normally we can use mathematical symbols (+, -, *, /) but how do we use these with arrays?
123
(Taras)
March 25, 2023, 1:37pm
2
Jinja2 's Built-in filters
If you want to divide by 2, multiply by 0.5.
If you want to add/subtract, you’ll need to use a for-loop.
Thanks for your answer, but frankly, that’s crazy!
The one line array manipulation is so elegant, I can’t believe it only supports one out of four maths operators (and a second with the inelegant workaround of multiplying by the inverse, as you pointed out)
The four math operators are pretty basic stuff. They really should be supported!
123
(Taras)
March 25, 2023, 1:56pm
4
Jinja is an open-source project so feel free to contribute/comment there.
Troon
(Troon)
March 25, 2023, 5:23pm
5
It looks as though multiply
isn’t documented — it’s not on the Jinja page, I can’t find it in their repository, and it isn’t a Python method on int
…
Edit: Found it in HA. Currently line 1520 of this file:
"""Template helper methods for rendering strings with Home Assistant data."""
from __future__ import annotations
from ast import literal_eval
import asyncio
import base64
import collections.abc
from collections.abc import Callable, Collection, Generator, Iterable
from contextlib import contextmanager, suppress
from contextvars import ContextVar
from datetime import datetime, timedelta
from functools import cache, lru_cache, partial, wraps
import json
import logging
import math
from operator import attrgetter, contains
import pathlib
import random
import re
import statistics
This file has been truncated. show original
Looks easy to submit a PR for add
and others.
Troon
(Troon)
October 19, 2023, 9:31am
6
Only took me seven months to work it out, but here’s a faked-up add
filter:
{{ [1,2,3,4]|batch(1)|map('sum',start=5)|list }}
4 Likes
123
(Taras)
October 19, 2023, 12:07pm
7
Thanks! Nice work!
I was unfamiliar with the batch
filter and the online examples focused on its ability to reformat HTML tables so I failed to grasp its utility for Home Assistant applications. However, your example makes me understand its strength is its ability to generate a “list of lists”. That allows map
to be applied to each item in the original list.
Thanks again for this useful example.
1 Like
Troon
(Troon)
February 7, 2024, 4:10pm
8
I’ve submitted a PR to add add
— let’s see what happens.
1 Like
Troon
(Troon)
June 6, 2024, 5:30am
10
Just dropped in 2024.6. We can now do things like array conversion of °C to °F:
{{ [-40, -18, 0, 100]
|map('multiply', 1.8)
|map('add', 32)
|map('int')
|list }}
The documentation now includes multiply
and add
at the end of this section:
3 Likes