-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
map_values and select work together? #970
Comments
Indeed, it doesn't. But for |
You can use
produces:
|
Not because of the way |
Even if |
@nicowilliams wrote:
If we use
Thus I think it's reasonable to say that it's the black-hole-like behavior of "empty" that makes the difference here. |
@pkoppstein Really, this is NOT about |
@nicowilliams - The difference between:
and
is that in the second case, "empty" appears instead of "null". Furthermore, any JSON value in the place of that null will not cause the "implosion" that "empty" produces. So whatever else can be said, it's clear that it's "empty" that makes the difference here. Of course if you were to change |= then that would make a difference, too, but we're talking here about the behavior of jq-as-it-is, not jq as-it-might-be. |
But it's nothing about |
Call it a bug or shortcoming of |
@nicowilliams wrote:
Hopefully "others" will speak up if they feel the need to. I never spoke about short-comings in this thread, least of all about empty; on the contrary, I suggested to the OP that with_entries would do what was wanted. |
Here's a version of
This deletes any keys in the input when the filter produces no outputs, otherwise it updates the value for each key to the first output of the given filter on the value at that key. This isn't quite right as it doesn't work for array inputs for the obvious reason that if we delete items from the array while traversing it forwards... we get confused. But it works for object inputs, and making it also work for array inputs is left as an exercise for the reader :) EDIT: Hint: replace the expression to reduce over with Example:
And as you can see, We couldn't make Someday I'll make it possible to import specific versions of the "jq core" module, then we could in fact make backwards-incompatible changes to things like |
Or, perhaps since the |
I think there are 4 possibilities we need to evaluate.
Overall my favorite at this point is option 4. I don't think it makes sense to leave option 1 to go to option 2 or 3, and later have a second break to go to option 4. Maybe we should document this case as unspecified behavior, and plan to do option 4 as part of a bigger break - unless of course I am missing downsides of option 4. |
@dtolnay Regarding (2), the author of the Yes, I've decided I like (2) better than (3). As to having to update OR remove, the way the reduction in
Something like (UNTESTED):
|
First, thanks to @dtolnay for laying out the alternatives so clearly and reasonably. Second, I'd agree with @dtolnay that (1) can safely be viewed as a bug. Indeed, the following variant might well be viewed as a serious bug:
At any rate, I cannot imagine many people intentionally relying on such behavior. Regarding the merits of (2), (3) and (4), I'd say that, although (4) has the advantage of consistency with the ordinary understanding of |=, it has the drawback of being fairly useless: inexpert users will (sooner or later) find it surprising or annoying; and expert users will almost always want to avoid it. Regarding the statement in the manual that: "If the right-hand side outputs multiple values, only the last one will be used.", I have a question: If we were free of that constraint, would that make a difference with respect to the choice between (2) and (3)? |
@pkoppstein I agree that (4) would be surprising and useless. To break out of a looping control structure ( As to taking the first or last value output by the RHS, it makes no difference to the choice between (2) and (3) (in my (3) makes some sense, but if you want to leave a path/value unchanged, just output the value (the RHS' input). OTOH, (2) could be surprising too, and (3) seems like the least surprising behavior -- just not the most useful. I suppose we could introduce a new builtin/syntax to use instead of |
@nicowilliams wrote:
The issue that @dtolnay and I had in mind was whether |= should subvert the normal backtracking behavior. That is, Perhaps I can be persuaded otherwise, but this seems like a misfeature that is severe enough to justify an imminent jq 2.0. |
I can see why (4) may be fairly useless. I agree that (2) is better than (3), and I think we can safely move to (2) as long as we preserve the current behavior when one or more values are produced by the rhs. There are a few more cases to pin down before coding this up:
|
@pkoppstein do you mean |
@dtolnay asked:
Absolutely not. I was, on the contrary, suggesting that |= should be brought back into conformance with jq's general approach to backtracking. The question in my mind is whether this would "require" a jump in numbering to 2.0, or whether that statement in the manual can be regarded as a bug. |
@dtolnay For the first corner case I already gave an answer ( |
I agree that |
Yeah, I'd call that a bug. |
@pkoppstein When you write things like "whether |= should subvert the normal backtracking behavior", I have no idea what you mean (is it code for how I really don't want to re-litigate the behavior of |
@nicowilliams wrote:
In that case, that is, if |
@pkoppstein No, That said, we could make
or more backwards-incompatibly:
I think it's too late for this, and I'm absolutely not interested in it nor in a 2.0 for this either. I do note that we could declare And there, we've re-litigated this :( |
For comparison,
This means that if For other readers,
Here the We could define
to attempt to get similar behavior to |
@pkoppstein Ah, perhaps you just want more cartesian product behavior because that's so easy to get in jq. But because function arguments are closures, functions can use them to build new control structures -- cartesian product behavior needn't always be what you get. I don't believe we can get anything like useful cartesian product behavior out of |
@nicowilliams wrote:
I thought that was obvious.
Yes, e.g. generate-and-test. If it's good enough for = it should be good enough for |=. |
@pkoppstein No, as I said, when you write about "subverting normal backtracking behavior" I have no clue what you mean. If you have a |
@nicowilliams - @dtolnay favored #4 (with backtracking, as I understand it), so I would expect he doesn't see any problem implementing it. In fact, if you would agree beforehand to give serious consideration to his implementation of #4 (with backtracking), maybe he'd be less reluctant to work on it :-) |
Tomorrow I'll post an implementation of what i think you want @ploppstein.
I don't like it for a variety of reasons, not the least of which is that it
makes `|=` not O(1) for memory consumption, but you'll get to see for
yourself.
The idea is to first collect the paths into an array, then collect the
updates for each path into an array, and then those updates into a larger
array where the elements at each index correspond to the corresponding
path's index in the array of paths. Then find the length of the longest
set of updates `range()` to that, then reduce over the paths applying to
the original input the edit corresponding to the path and update index,
arranging -perhaps- to delete paths where no update was produced. This
will get you Cartesian product behavior, sort of. It isn't and can't be
the analog if `=` that you want because there's no guarantee that the
update closure will produce the same number of outputs at each path. This
is email written on a mobile device, so pardon typos and lack of code.
|
@nicwilliams wrote:
I'm greatly honored! But if it's not possible to implement |= in a way that ensures |
I experienced this issue today. The manual implies |
@amckinlay - As pointed out in this thread, the simplest workaround is to avoid using
If you find this or any other definition of map_values/1 to be superior to the one currently provided (in builtin.jq), then please indicate as much here. |
I stumbled upon this issue after having a similar problem. Of note, I have According to the 1.6 playground (https://jqplay.org/s/jprJeMQtYl), this now works as expected! 🎉 |
Hi, shouldn't this work?
https://jqplay.org/jq?q=.toto%20|%20map_values(select(.x==%22t%22))&j={%22toto%22:%20{%22a%22:%20{%22x%22:%20%22t%22},%20%22b%22:%20{%22x%22:%20%22t%22},%20%22c%22:%20{%22x%22:%20%22r%22}}}
The output I was expecting was:
The text was updated successfully, but these errors were encountered: