Phrogz / NeatJSON

Pretty-print your JSON in Ruby, JS, or Lua with more power than JSON.stringify or JSON.pretty_generate
http://phrogz.net/JS/NeatJSON
MIT License
108 stars 19 forks source link

Would like to have an explicit control over sorting the keys #16

Closed bwl21 closed 8 years ago

bwl21 commented 8 years ago

I would like to have explicit control about the order of the keys. I have implemented in https://github.com/bwl21/NeatJSON/tree/feature/explicit_sort.

It is controlled by options:

`explicit_sort: [[:e, :d,],[:b, :a]]}``

This is the testcase

    {value:{a:1, b:2, c:{a:1, b:2}, d: 3, e:4}, tests:[
        { json:%Q{{"e":4,"d":3,"c":{"b":2,"a":1},"b":2,"a":1}}, 
                     opts:{wrap:false, explicit_sort: [[:e, :d,],[:b, :a]]} },
        { json:%Q{{"e":4,"d":3,"b":2,"a":1,"c":{"b":2,"a":1}}}, 
                     opts:{wrap:false, explicit_sort: [[:e, :d,],[:b, :a, :c]]} },
        { json:%Q{{
  "e":4,
  "d":3,
  "c":{
    "b":2,
    "a":1
  },
  "b":2,
  "a":1
}},
              opts:{wrap:1, explicit_sort: [[:e, :d,],[:b, :a]]} },
        { json:%Q{{"e":4,
 "d":3,
 "c":{"b":2,
      "a":1},
 "b":2,
 "a":1}}, 
opts:{short:true, wrap:1, explicit_sort: [[:e, :d,],[:b, :a]]} }
    ]}

I can prepare a pull request if you would be willing to integrate that. It depends/conflicts with pr #15. So we should decide #15 one first.

Phrogz commented 8 years ago

The unlabeled "keys at beginning" and "keys at end" seems to me to be overly specific, not generally useful enough for everyone. How about:

opts:{ sorted:function(key,value,object){ return someOrderingValue } } // JS
opts:{ sorted:->(key,value,object){ someOrderingValue } }              # Ruby

in which case you can choose to create your own lookup that does what you want, or others can order based on value instead of key, etc.

For example, you could:

// JavaScript
var keyOrder = {e:1, d:1, b:9, a:9};
neatJSON(myObject, { wrap:40, sorted:function(k){ return keyOrder[k] || 5 } });
# Ruby
key_order = {e:1, d:1, b:9, a:9}
key_order.default = 5
JSON.neat_generate my_object, wrap:40, sorted:->(k){ key_order[k] }
Phrogz commented 8 years ago

I have added the sort:lambda feature in e85c1662fdd and released as v0.8

bwl21 commented 8 years ago

Thanks for implementing this. The approach is more generic than mine and allows to achieve what I want.

But you introduced a new patten which I did not dare to do: options itself can no longer be expressed as JSON in all cases. I am not sure if this is a strong requirement, but I think it was at least a nice to have.

bwl21 commented 8 years ago

Had another look into this. I would like to give my user full control over sorting. Therefore it is required, that the neatjson options can be represented as JSON.

I fully agree that the unlabeled keys are not very expressive.

explicit_sort: {before:[:e, :d,], after:[:b, :a]]}

You have renamed the option from sorted to sort. Wouldn't it be better to keep the sortedand provide the sort as an extra option. In my approach, I could control the sorting of those keys which were not covered by the explicit_sort.

But my main concern is the fact that options can no longer be expressed as javascript.