Is it possible to do expressions/calculations in json?

最后都变了- 提交于 2019-12-22 10:54:55

问题


I am using the wonderful json-server as the backend of my application and it's really useful for hitting custom endpoints to retrieve some data. but what would be super useful if it allowed me to do calculations/expression so that i can mimic that backend behaviour too.

take this data structure for example

{
  "products": [
    {
      "name": "football",
      "id": "SPO-001",
      "category": "sport",
      "price": 40,
      "couponApplied": "false",
      "coupons": [
        "daw124qdw",
        "a1212cxn"
      ]
    }
  ]
}

I would like some way of saying something like "discountPrice": couponApplied ? price * couponDiscount

that's just me pseudo coding. but I would like to do something where I can calculate the price on the fly. or when I make a request it does a calculation and returns me the calculated data (like a backend app would)

I understand I can make a request, apply the coupon and render that new price. or even make a post request and change the price. but that is all done client side. is there any way to do this either with json or json-server or any other solutions. if that makes sense?


回答1:


JSON means JavaScript Object Notation and is data structure, and does not have any preprocessor for it. You can use any JSON parser and append/change values that you need dynamically.

So in short: no, there is no possibility to add dynamic values




回答2:


No, you'll not be able to do computations inside json. The data would need to be mutated elsewhere and then sent.




回答3:


No, it isn't possible to do math or any kind of expression in JSON as JSON is just a data structure format, and not a programming language.

You will need to load the JSON data in using a programming language of your choice, at which point you can then manipulate it.

For example, since you mention javascript a simple Node program as an example..

//It would be better to use the FileSystem API, but for simplicity for this example, I'm using require
var json = require('./myjson.json'); 
var product = json.products[0];

//Since the dataset has "false", this if will handle both "false" (string) and false (boolean) values. The value should really be boolean if possible
product.discountPrice = product.couponApplied && product.couponApplied !== "false" ? product.price * couponDiscount : null;



回答4:


If you are trying to create logic dynamically, like user creates some logic, and you want to save it into DB and later apply it somewhere, these might be useful:

  • An Excel like formula parser + a bit of JS codes to put data into formulas.
  • JSONLogic
  • MongoDB aggregation pipeline operations are being used in an Array of Object. Same behavior can be used inside JSON object, but you need an implementation to take care of it, something like Mingo. Check arithmetic sum for example. This JS implementation might help.

In your example, using formula parser could be like:

const response = {
  "products": [
    {
      "name": "football",
      "id": "SPO-001",
      "category": "sport",
      "price": 40,
      "couponApplied": "false",
      "coupons": [
        "daw124qdw",
        "a1212cxn"
      ]
    },
    {
      "name": "football",
      "id": "SPO-001",
      "category": "sport",
      "price": 40,
      "couponApplied": "true",
      "couponDiscount": 0.2,
      "coupons": [
        "daw124qdw",
        "a1212cxn"
      ]
    }
  ],
  formulaFields: {
    "discountPrice": 'IF("{couponApplied}"="true", {price} * {couponDiscount}, "")', // excel standard formula, with {variable} as product field keys
  }
}

const productsWithValues = response.products.map((product)=>{
  const productWithValues = { ...product };
  for (const field in response.formulaFields){
    const formula = response.formulaFields[field].replace(/\{([^\}]+)\}/g, (_, key) => product[key])
    const parser = new Parser();
    const { result } = parser.parse(formula);
    productWithValues[field] = result;
  }
  return productWithValues;
})
console.log(productsWithValues)

Output:

[
  {
    "name": "football",
    "id": "SPO-001",
    "category": "sport",
    "price": 40,
    "couponApplied": "false",
    "coupons": ["daw124qdw", "a1212cxn"],
    "discountPrice": null
  },
  {
    "name": "football",
    "id": "SPO-001",
    "category": "sport",
    "price": 40,
    "couponApplied": "true",
    "couponDiscount": 0.2,
    "coupons": ["daw124qdw", "a1212cxn"],
    "discountPrice": 8
  }
]



回答5:


JSON doesn't support this, but if you turn it into a Javascript object, you could do something like this:

var obj = JSON.parse(
`{
  "products": [
    {
      "name": "football",
      "id": "SPO-001",
      "category": "sport",
      "price": 40,
      "couponApplied": "true",
      "couponDiscount": 0.5,
      "coupons": [
        "daw124qdw",
        "a1212cxn"
      ]
    }
  ]
}`).products[0];

Object.defineProperty(obj,"discountPrice",{
  get:function(){
    return (this.couponApplied==="true"||this.couponApplied===true) ? this.price*this.couponDiscount : this.price;
  },
  set:function(){
    return;
  }
});

console.log(obj.discountPrice);

This uses an accessor descriptor to define an object property that depends on the values of the other object properties.




回答6:


Note that json-server allow you to add custom middleware. So you could write something like this:

const updateProduct = (p) => ({
  ...p,
  discountPrice: p.couponApplied ? p.price * p.couponDiscount : p.price
})

const transform = ({products, ...rest}) => ({
  ...rest, 
  products: products.map(updateProduct)
})

const modify = (req, res, next) => {
  if (req.path !== '/my-route') return next();

  res.body = JSON.stringify(transform(JSON.parse(res.body)))
  next();
}


// dummy call -- would really be handled by json-server/express

(() => {
  const req = {path: '/my-route'};
  const res = {body: `{"products":[{"name":"football","id":"SPO-001","category":"sport","price":40,"couponApplied":false,"coupons":["daw124qdw","a1212cxn"]},{"name":"helmet","id":"SPO-042","category":"sport","price":50,"couponApplied":true,"couponDiscount":0.75,"coupons":["foobarbaz"]}]}`}
  const next = () => {console.log(JSON.parse(res.body))}
  
  modify(req, res, next)
})()


来源:https://stackoverflow.com/questions/53870341/is-it-possible-to-do-expressions-calculations-in-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!