Code Monkey home page Code Monkey logo

Comments (16)

ohler55 avatar ohler55 commented on June 14, 2024 1

Almost but not quite. Let me try providing an example.

First the collection or map alternative:

type OrderedMap struct {
	m    map[string]any
	keys []string
}

func (om *OrderedMap) ValueForKey(key string) any {
	return om.m[key]
}

func (om *OrderedMap) Keys() []string {
	return om.keys
}

The interface that the jp package would look for would be:

type Keyed interface {
	ValueForKey(key string) any
	Keys() []string
}

How that would work internally is that when evaluating the JSONPath (jp.Expr) the calls to walk over the OrderMap would use the interface calls to get keys and values. This was just my first thoughts so the actual interface might be different.

from ojg.

ohler55 avatar ohler55 commented on June 14, 2024 1

It will be an enhancement so nothing exiting will change from the user perspective. I've get it in this weekend but might take a few extra days for tests.

from ojg.

ohler55 avatar ohler55 commented on June 14, 2024 1

If you would like to see how this would work take a look at the "keyed-indexed" branch and the end of the get_test.go file. Just a few expressions have been implemented so far and the test demonstrates them. Not that I combined the map and slice alternatives into one type. That is not required but only to simplify testing.

from ojg.

ohler55 avatar ohler55 commented on June 14, 2024 1

Good to hear. I still haven't finished the set and modify calls yet and filters have not been done either but that should happen over the next few days.

from ojg.

ohler55 avatar ohler55 commented on June 14, 2024 1

Tests completed. If you haven't run into any issues I'll make a release.

from ojg.

ohler55 avatar ohler55 commented on June 14, 2024

It is not possible right now. If I understand correctly you would like an option to use something other than map[string]any for JSON objects created during parsing. I suppose the more general case would be to provide types or functions for all types or maybe a callback parser. Is that right?

from ojg.

adrienaury avatar adrienaury commented on June 14, 2024

Yes exactly :)

from ojg.

ohler55 avatar ohler55 commented on June 14, 2024

Using alternatives for each element type is a rather specialized case. Another approach that would give you what you want would be a callback parser like SAX but for JSON. That I would consider adding although I'm not sure how different it would be to the oj.Tokenizer. What do you think?

from ojg.

adrienaury avatar adrienaury commented on June 14, 2024

Maybe let me be more specific,
I would like to be able to continue using jsonpath expressions on the resulting object, and preserving key order, at all levels.

row := oj.MustParseString(`{"b":0, "a":1, "c":2}`, &ojg.Options{KeepKeyOrder: true})
query := jp.MustParseString("$.b")
fmt.Println(query.Get(row)) // output 0
fmt.Println(oj.JSON(row)) // output : {"b":0, "a":1, "c":2}

With the current version of the library, the last output would give a random order of keys

fmt.Println(oj.JSON(row)) // output : {"a":1, "c":2, "b":0} or any other order of keys

I'm not sure how different it would be to the oj.Tokenizer.

I tried to use a custom oj.Tokenizer, but it didn't work because, JSONPath queries stopped working

from ojg.

ohler55 avatar ohler55 commented on June 14, 2024

Maps are unordered but JSONPath understand them. JSONPath does not know about new collection types like the one you are proposing. So the second part of going from parsing to access would have to be something that looked for a match on an interface that allowed for indexing the collection by either a string or an integer. That might be the enhancement you are looking for. Is that correct?

from ojg.

adrienaury avatar adrienaury commented on June 14, 2024

I don’t know if I understand correctly, but the order should not be part of the data. When you mention a match on an interface, is it about a way for the jsonpath engine to understand that the key order is important so it must adapt its algorithm to know how to read an objects with its keys? In this case, I think yes it respond to what I am looking for, because it would be an internal detail about how to « scan » for objects keys.

Let me know if I didn’t understand

from ojg.

adrienaury avatar adrienaury commented on June 14, 2024

To complete my previous response:

I think the parser could use this struct when the KeyOrder option is active, in place of a map[string]any

type object struct {
  m map[string]any // object keys / values map
  keys []string // order in witch keys should be accessed
}

The the JSONPath engine could access object keys like this when it detects an object struct

obj.m[key] // instead of obj[key]

Finally, the conversion to JSON could use a range over the keys instead of over the map, when it detects an object struct

for _, key := range obj.keys: // instead of : for key, value := range obj:
   value := obj.m[key] // process to output key/value pair as JSON

from ojg.

adrienaury avatar adrienaury commented on June 14, 2024

This is even better I agree.

Thank you for taking time with me :)

Do you think that solution would be easy to implement without breaking anything on the current version ?

from ojg.

adrienaury avatar adrienaury commented on June 14, 2024

I see that if I parse the JSON into objects that implements the Keyed interface, then jp expressions will work fine. This is already a huge step toward my goal! Thank you @ohler55 :)

The parser should understand the Keyed (and Indexed) interface to output keys in the correct order, but for this part I know I can do it with a custom code.

I will be able do test it extensively in the next few weeks because it will be use on a new tool we are working on in my organisation

from ojg.

adrienaury avatar adrienaury commented on June 14, 2024

Thank you, I did some tests yesterday, everything went fine with Get and Set.
So far so good :) you can launch the release 🚀

from ojg.

ohler55 avatar ohler55 commented on June 14, 2024

Released v1.18.2

from ojg.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.