Skip to content
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

cli: option -k to preserve the order of keys #239

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

starius
Copy link

@starius starius commented Jan 19, 2024

I read feedback on #189 and #84 and implemented it in a way that does not change gojq (the library). Also it is completely optional and it only affects encoding and decoding. Everything in between is the same. Still it covers majority of my jq uses: pretty printing, extraction by path. Maps in JSON are often Go structs and preserving the order improves readability a lot.

It builds an external map from object pointer to the list of keys as seen in the input. If an object does not change during the whole operation of gojq, cli can find the original order of keys during encoding by looking into the map and checking if the set of keys is the same. This works for both JSON and YAML.

go-ordered-map is used as an intermediate object created during decoding and encoding (in case of YAML). After parsing is done, the list of keys is extracted from orderedmap and the map is turned into a regular map[string]any. A pointer to that map is added to a global table map[uintptr][]string which stores the order of keys. When encoding, this data is used to put keys in the right order.

Example:

$ echo '{"tx": {"open": 1, "close": 2}, "accept": true}' | gojq . 
{
  "accept": true,
  "tx": {
    "close": 2,
    "open": 1
  }
}

$ echo '{"tx": {"open": 1, "close": 2}, "accept": true}' | gojq -k . 
{
  "tx": {
    "open": 1,
    "close": 2
  },
  "accept": true
}

It builds an external map from object pointer to the list of keys as seen in the
input. If an object does not change during the whole operation of gojq, cli can
find the original order of keys during encoding by looking into the map and
checking if the set of keys is the same. This works for both JSON and YAML.

Type orderedmap is used as an intermediate object created during decoding and
encoding (in case of YAML). After parsing is done, the list of keys is extracted
from orderedmap and the map is turned into a regular map[string]any. A pointer
to that map is added to a global table map[uintptr][]string which stores the
order of keys. When encoding, this data is used to put keys in the right order.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant