Here is JSON:
{
"a": [
"foo",
"bar",
"test"
]
}
The idea is to replace bar
by bar_new
, if bar
is present in the array.
The desired output will be:
[
"foo",
"bar_new",
"test"
]
So, if we don't have bar
in the input JSON, the output will be:
[
"foo",
"test"
]
I've tried to put it together by map()
and join()
functions, but join()
function returns a string instead of an array.
I need exactly this array in the output.
Here is a solution, the only caveat is that it does not replace the element bar
, it removes it out of the array and appends an element bar_new
if there was an element bar
in the first place.
So, effectively the element bar_new
is not guaranteed to be at the same index as bar
was.
In JMESPath you cannot do an if ... else ...
, but you can apply the same principle as you will sometimes find in shell scripts where we can do
some_instruction \
&& another_instruction_when_the_first_one_is_successful \
|| yet_another_instruction_when_the_first_one_fail
So, in your case you can start by saying:
bar
in the array, return me an altered version of the array:
bar
bar_new
bar
in the array (effectively, an else), return me the array in a
Finding an element in an array is quite simple, given that this is the role of the function contains()
.
Giving you a query like:
(contains(a, `bar`) && [`new_array_here`]) || a
Knowing how to append an element in an array is a tricky one, there is no easy concatenation between arrays in JMESPath, this said, you can create an array of arrays and flatten it.
For example:
[[`a`,`b`],`c`] | []
Would result in
[
"a",
"b",
"c"
]
Combining all of this, the query
(contains(a, `bar`) && [a[? @ != `bar`], `bar_new`] | []) || a
Would yield, with your example JSON,
[
"foo",
"test",
"bar_new"
]