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

toObject and fromObject #1679

Open
aalexgabi opened this issue Nov 22, 2019 · 7 comments
Open

toObject and fromObject #1679

aalexgabi opened this issue Nov 22, 2019 · 7 comments

Comments

@aalexgabi
Copy link

I can serialize and de-serialize an expression to JSON as shown here: https://mathjs.org/docs/core/serialization.html

In my application the expression is part of a bigger JSON which is de-serialized at a higher level. I would need to de-serialize an expression from an object like this:

const node = math.parse('age >= 21 ? 999 + 5 : 111 + 2')
const objectExpression = node.toObject();
const node2 = math.fromObject(objectExpression)

Of course I could do something like this but it's not optimal because I would have to serialize the object to JSON first:

const node = math.parse('age >= 21 ? 999 + 5 : 111 + 2')
const json = JSON.stringify(node);
const expression = JSON.parse(json, math.revive);

Is there a way to do this without calling the revive function recursively? I tried to use map-keys-deep but the reviver gets called for a parent leaf and then for the child and it seems that the order need to be reversed to use the revive function.

@aalexgabi
Copy link
Author

I have been able to do it this way using deepdash:

console.log('tree', tree);
const restoredNode = mapDeep(tree, (value, key, object, info) => {
    if (info.afterIterate) {
        return math.reviver(key, value);
    }

    return value;
}, {
    callbackAfterIterate: true,
});
console.log('node', restoredNode);

Which prints:

tree {
  mathjs: 'OperatorNode',
  op: '+',
  fn: 'add',
  args: [
    { mathjs: 'SymbolNode', name: 'age' },
    { mathjs: 'ConstantNode', value: 21 }
  ],
  implicit: false
}
node Node {
  implicit: false,
  op: '+',
  fn: 'add',
  args: [ Node { name: 'age' }, Node { value: 21 } ]
}

It would be nice if the library would support this natively.

@josdejong
Copy link
Owner

I get what you mean. That's interesting. You want to turn mathjs objects into plain JSON objects (non-stringified).

A simple (not very efficient) solution is to do it like this:

function toObject(mathjsObject) {
  return JSON.parse(JSON.stringify(mathjsObject))
}

function fromObject(jsonObject) {
  return JSON.parse(JSON.stringify(jsonObject), math.json.reviver)
}

I suppose your "higher level serialization" is not customizable in such a way that it can embrace the provided reviver? I think that would be even better. Your proposed solution is to first turn mathjs objects into JSON objects, and next serialize these JSON objects. That's still two steps, still not optimal. Can you explain a bit more about your use case Aalex?

@aalexgabi
Copy link
Author

@josdejong I receive JSON messages from an MQ broker. The MQ library automatically de-serializes messages and passes them to a handler function. Somewhere deep inside the handler function math.js is called with a part of the whole object to evaluate an expression.

The message contains multiple dynamic properties which are math.js expressions and are evaluated for a given context (scope).

@josdejong
Copy link
Owner

Thanks for the context Aalex, that makes sense.

I think your idea of fromObject and toObject is indeed worth implementing. It will give another powerful option for serialization/deserialization like your use case, and I expect it will be not that much code.

Anyone interested in implementing fromObject and toObject?

@josdejong
Copy link
Owner

Funny: https://www.bram.us/2019/11/25/faster-javascript-apps-with-json-parse/

I don't think it will apply to our case here, but it could be a good idea to do some real world benchmarking :)

@mattvague
Copy link
Sponsor Contributor

@josdejong I think I'm in need of this functionality, would you be opposed to a PR implementing it?

@josdejong
Copy link
Owner

Thanks Matt, a PR would be very welcome, I see your draft in #2774

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants