gron icon indicating copy to clipboard operation
gron copied to clipboard

--no-sort option is unstable

Open slafs opened this issue 3 years ago • 5 comments

For a simple JSON doc

{"z": "first", "a": "last"}

gron --no-sort keeps producing wrong results at around 12% rate.

Tried it with:

$ for i in $( seq 1000 ); do echo '{"z": "first", "a": "last"}' | gron --no-sort | column -x; done | sort | uniq -c
 125 json = {};		json.a = "last";	json.z = "first";
 875 json = {};		json.z = "first";	json.a = "last";

Tried it with:

$ gron --version
gron version dev
$ brew info gron
gron: stable 0.7.1 (bottled), HEAD
Make JSON greppable
https://github.com/tomnomnom/gron
/usr/local/Cellar/gron/0.7.1 (4 files, 5MB) *
  Poured from bottle on 2022-06-29 at 13:56:51
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/gron.rb
License: MIT
==> Dependencies
Build: go ✘
==> Options
--HEAD
	Install HEAD version
==> Analytics
install: 878 (30 days), 2,899 (90 days), 5,560 (365 days)
install-on-request: 876 (30 days), 2,899 (90 days), 5,561 (365 days)
build-error: 0 (30 days)

$ brew list gron
/usr/local/Cellar/gron/0.7.1/bin/gron

slafs avatar Jun 29 '22 12:06 slafs

BTW this tool is fantastic and helps me a lot! Thanks for creating it :)

slafs avatar Jun 29 '22 12:06 slafs

--no-sort tells gron not to sort the output. It doesn't guarantee a stable order - if you want that, let it sort. The instability comes from the underlying Go map object, which randomizes string hashing functions.

RossPatterson avatar Jul 01 '22 01:07 RossPatterson

Well, I guessed that might be the cause, but the underlying implementation shouldn't matter, right? The option is confusing when it works this way. What's the use of a non-sorted output if the input is being modified in the first place 😅?

slafs avatar Sep 19 '22 08:09 slafs

Hi, I just tried with the tool I wrote ( https://github.com/adamritter/fastgron ), it preserves the order with gron (I'm not sure about ungron though yet :( )

for i in $( seq 1000 ); do echo '{"z": "first", "a": "last"}' | gron --no-sort | column -x; done | sort | uniq -c;

130 json = {}; json.a = "last"; json.z = "first"; 870 json = {}; json.z = "first"; json.a = "last"; (base) ➜ ~/Documents/GitHub/fastgron/fastgron git:(main) for i in $( seq 1000 ); do echo '{"z": "first", "a": "last"}' | fastgron --no-sort | column -x; done | sort | uniq -c;

1000 json = {} json.z = "first" json.a = "last"

adamritter avatar Jul 04 '23 20:07 adamritter

+1 to --no-sort preserving input order if that's not to difficult to implement. Right now there is no way to retain order, but order often is often explicitly set in JSON objects to aid in interpretation / human-legibility.

dhimmel avatar Jan 12 '24 22:01 dhimmel