Reputation: 394
Given the input:
data = [{'leagues': [{'id': 2294162, 'sport': 'S'}, {'id': 8541851, 'sport': 'S'}]},
{'leagues': []},
{'leagues': [{'id': 2228013, 'sport': 'B'}]}]
I want to generate the following output:
result = ['2294162%238541851&ttgIds=S@', '2228013&ttgIds=B@']
I am close, but I am unable to extract and join the sport values correctly:
jmespath.search("[?not_null(@.leagues)].leagues[*].id.to_string(@) | [*].join(', ', @).join('', [[@],['&ttgIds=', '@']][]).replace(@, ', ', '%23')", data=data)
output = ['2294162%238541851&ttgIds=@', '2228013&ttgIds=@']
I tried using let
, but the output is empty:
jmespath.search("[?not_null(@.leagues)].leagues[*].let $sport_id = sport in id.to_string(@) | [*].join(', ', @).join('', [[@],['&ttgIds=', $sport_id, '@']][]).replace(@, ', ', '%23')", data=data)
output = [[], []]
Does anyone have an idea on how to solve this?
Upvotes: 0
Views: 68
Reputation: 993
Your post seem to be incomplete, because in fact it's nearly always possible to reach the objective in JMESPath, but the real question is about to do it dynamically or not.
Here's a solution for your problem :
[[email protected]].leagues[*].[@.id.to_string(@),@.sport] | [*][*].join(',',@) | [*].join(';',@) | @.replace(@,',S;','%23').replace(@,',@','@').replace(@,',','&ttgIds=')
here's the result :
["2294162%238541851&ttgIds=S@", "2228013&ttgIds=B@"]
First of all I couldn't test entirely my code because in the official website of JMESPATH there is no replace
function. So after [*].join(';',@) |
I'm not sure if it's work or not, but by looking your code I could guess how replace
function works.
You said previously that I am unable to extract and join the sport values correctly
, you were in this situation because you didn't bring the attribute sport
in the rest of the code, just selected the id
attribute in this portion of code leagues[*].id.to_string(@)
Here's the testable solution on the official website:
[[email protected]].leagues[*].[@.id.to_string(@),@.sport] | [*][*].join(',',@) | [*].join(';',@) | @
Here's the result :
[
"2294162,S;8541851,S,@",
"2228013,B,@"
]
As you can see if you replace the ,S;
by %23
then ,@
by @
then ,
by &ttgIds=
it will give you this result
[
"2294162%238541851&ttgIds=S@",
"2228013&ttgIds=B@"
]
BUT
As I mentionned earlier, JMESPath all about dynamism... As you an see is this portion of code @.replace(@,',S;','%23')
I put S
in a hardcoded way... so if you json got another letter than S this code will not work. My solution is valid if it's always an S, if there other values that you know in advance like A,B,C,G,etc... you can just insert replace(@,',A;','%23').replace(@,',B;','%23').replace(@,',C;','%23').replace(@,',G;','%23')
. The only purpose with this solution is about the length of string, it could be pretty long if you have many possibility of values for the attribute sport.
However if you don't know the values taken by sport attribute you can't use my solution.
**PS : ** In the official website the not_null
function didn't work so I just cut from the solution but with just [[email protected]]
we can already filtering to get only array leagues that's not empty array.
Upvotes: 1