可以在json中执行表达式/计算吗?

时间:2018-12-20 14:13:17

标签: javascript json reactjs json-server

我正在使用出色的json服务器作为应用程序的后端,它对于点击自定义端点以检索某些数据确实很有用。但是,如果它允许我进行计算/表达式以使我也可以模仿该后端行为,那将是超级有用的。

以这种数据结构为例

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

我想说一种类似"discountPrice": couponApplied ? price * couponDiscount

的方式

那只是我的伪编码。但我想做一些可以即时计算价格的事情。或在我发出请求时进行计算并向我返回计算出的数据(就像后端应用程序一样)

我知道我可以提出请求,申请优惠券并提供新价格。甚至发帖要求并更改价格。但这都是在客户端完成的。有没有办法用json或json-server或任何其他解决方案来做到这一点。那有道理吗?

6 个答案:

答案 0 :(得分:5)

JSON的意思是JavaScript Object Notation,它是数据结构,并且没有任何预处理程序。您可以使用任何JSON解析器并动态添加/更改所需的值。

简而言之:不,不可能添加动态值

答案 1 :(得分:2)

否,您将无法在json中进行计算。数据需要在其他地方进行变异然后再发送。

答案 2 :(得分:1)

否,因为JSON只是一种数据结构格式,而不是编程语言,因此无法在JSON中进行数学运算或任何形式的表达。

您将需要使用您选择的编程语言来加载JSON数据,然后您就可以对其进行操作了。

例如,既然您提到javascript,则以一个简单的Node程序为例。

//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;

答案 3 :(得分:0)

JSON不支持此功能,但是如果将其转换为Javascript对象,则可以执行以下操作:

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);

这使用访问器描述符来定义对象属性,该对象属性取决于其他对象属性的值。

答案 4 :(得分:0)

请注意,json-server允许您add custom middleware。所以你可以这样写:

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)
})()

答案 5 :(得分:0)

如果您尝试动态创建逻辑(例如用户创建一些逻辑),并且想要将其保存到数据库中,然后再将其应用到某处,则这些可能会很有用:

在您的示例中,使用公式解析器可能类似于:

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)

输出:

[
  {
    "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
  }
]