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
Add filter operation #1588
Add filter operation #1588
Conversation
pkg/yqlib/operator_filter.go
Outdated
childCtx := context.SingleReadonlyChildContext(result) | ||
include, err := d.GetMatchingNodes(childCtx, expressionNode.RHS) | ||
if err != nil { | ||
return Context{}, err | ||
} | ||
var includeResult bool | ||
var errDecoding error | ||
includeEl := include.MatchingNodes.Front() | ||
if includeEl.Next() != nil { | ||
return Context{}, errors.New("Only expected one child") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was the best way I could find to turn each value into a truthy value to determine if it should be included. LMK if there's a better way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, yeah there should be a cleaner way. What this function is basically doing is a map(select(X)).
You could create a new select
expression node and give the expression.RHS to it.
something like:
selectNodesOp := &ExpressionNode{
Operation: selectOp,
RHS: expression.RHS,
}
includedNodes, err := d.GetMatchingNodes(splatted, selectNodesOp.RHS)
Pretty sure this could be extended to create a map(select) expression and just delegate the logic to those functions entirely...
One thing I'm not super happy with is arrays-of-arrays. But it works the same for both
I'd rather see the latter output - - 2
- 3
- 4
- - 5
- 6
- 7 |
Yep - the first expression splats the array of arrays, which becomes the new context- and then it maps (or filters) that context. This is like the difference between: To get what you want - you'd need to run the expression without changing the context. You can use 'with' to that:
Hope that makes sense! |
pkg/yqlib/operator_filter_test.go
Outdated
expression: `filter(. < 3)`, | ||
expected: []string{ | ||
"D0, P[], (!!seq)::- 1\n", | ||
"D0, P[], (!!seq)::- 2\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this isn't actually the right result - this means the filter function is return two arrays - each with a single element. It should return a single array with two elements
"D0, P[], (!!seq)::- 1\n- 2\n",
I think if you refactor to use map and select under the hood - it would do the right thing.
Awesome, I didn't know about I also got it to do what I want with this expression:
|
Isn't |
Fixes #1586