Skip to content

Commit

Permalink
Sort by works on map
Browse files Browse the repository at this point in the history
  • Loading branch information
mikefarah committed Jan 22, 2025
1 parent 08092fa commit 4dfe52d
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 38 deletions.
14 changes: 3 additions & 11 deletions examples/data1.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
# block comments come through
person: # neither do comments on maps
name: Mike Wazowski # comments on values appear
pets:
- cat # comments on array values appear
- dog # comments on array values appear
- things:
- frog
food: [pizza] # comments on arrays do not
emptyArray: []
emptyMap: []
Foo: 3
apple: 1
bar: 2
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,4 @@ require (
golang.org/x/sys v0.28.0 // indirect
)

go 1.21.0

toolchain go1.22.5
go 1.23.0
23 changes: 23 additions & 0 deletions pkg/yqlib/candidate_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,29 @@ func (n *CandidateNode) SetParent(parent *CandidateNode) {
n.Parent = parent
}

type ValueVisitor func(*CandidateNode) error

func (n *CandidateNode) VisitValues(visitor ValueVisitor) error {
if n.Kind == MappingNode {
for i := 1; i < len(n.Content); i = i + 2 {
if err := visitor(n.Content[i]); err != nil {
return err
}
}
} else if n.Kind == SequenceNode {
for i := 0; i < len(n.Content); i = i + 1 {
if err := visitor(n.Content[i]); err != nil {
return err
}
}
}
return nil
}

func (n *CandidateNode) CanVisitValues() bool {
return n.Kind == MappingNode || n.Kind == SequenceNode
}

func (n *CandidateNode) AddKeyValueChild(rawKey *CandidateNode, rawValue *CandidateNode) (*CandidateNode, *CandidateNode) {
key := rawKey.Copy()
key.SetParent(n)
Expand Down
34 changes: 10 additions & 24 deletions pkg/yqlib/operator_sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,19 @@ func sortByOperator(d *dataTreeNavigator, context Context, expressionNode *Expre

var sortableArray sortableNodeArray

if candidate.Kind == MappingNode {

sortableArray = make(sortableNodeArray, len(candidate.Content)/2)
for i := 1; i < len(candidate.Content); i = i + 2 {

originalNode := candidate.Content[i]
compareContext, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(originalNode), expressionNode.RHS)
if candidate.CanVisitValues() {
sortableArray = make(sortableNodeArray, 0)
visitor := func(valueNode *CandidateNode) error {
compareContext, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(valueNode), expressionNode.RHS)
if err != nil {
return Context{}, err
return err
}

sortableArray[i/2] = sortableNode{Node: originalNode, CompareContext: compareContext, dateTimeLayout: context.GetDateTimeLayout()}

sortableNode := sortableNode{Node: valueNode, CompareContext: compareContext, dateTimeLayout: context.GetDateTimeLayout()}
sortableArray = append(sortableArray, sortableNode)
return nil
}

} else if candidate.Kind == SequenceNode {
sortableArray = make(sortableNodeArray, len(candidate.Content))

for i, originalNode := range candidate.Content {

compareContext, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(originalNode), expressionNode.RHS)
if err != nil {
return Context{}, err
}

sortableArray[i] = sortableNode{Node: originalNode, CompareContext: compareContext, dateTimeLayout: context.GetDateTimeLayout()}

if err := candidate.VisitValues(visitor); err != nil {
return context, err
}
} else {
return context, fmt.Errorf("node at path [%v] is not an array or map (it's a %v)", candidate.GetNicePath(), candidate.Tag)
Expand Down

0 comments on commit 4dfe52d

Please sign in to comment.