0

我开始使用react-jsonschema-form,它需要以特定格式输入。我得到了一个嵌套的 JSON,但我无法根据所需的输入格式递归地改变 JSON。

给定的是这个 JSON

{
  "Coordinates": {
    "X-Coordinate": 47,
    "Y-Coordinate": -122
  },
  "Coordination Type": {
    "Cartesion Mode": false,
    "Starting Range": {
      "Start": 8000,
      "End": 9000
    }
  },
  "Map": {
    "Offline Map": false,
    "URL": "http://localhost:9000"
  }
}

而这个新的 JSON 需要递归生成。

{
  "Coordinates": {
    "type": "object",
    "title": "Coordinates",
    "properties": {
      "X-Coordinate": {
        "type": "number",
        "title": "X-Coordinate",
        "default": 47
      },
      "Y-Coordinate": {
        "type": "number",
        "title": "Y-Coordinate",
        "default": -122
      }
    }
  },
  "Coordination Type": {
    "type": "object",
    "title": "Coordination Type",
    "properties": {
      "Cartesion Mode": {
        "type": "boolean",
        "title": "Cartesion Mode",
        "default": false
      },
      "Starting Range": {
        "type": "object",
        "title": "Start Range",
        "properties": {
          "Start": {
            "type": "number",
            "title": "Start",
            "default": 8000
          },
          "End": {
            "type": "number",
            "title": "End",
            "default": 9000
          }
        }
      }
    }
  },
  "Map": {
    "type": "object",
    "title": "Map",
    "properties": {
      "Offline Map": {
        "type": "boolean",
        "title": "Offline Map",
        "default": false
      },
      "URL": {
        "type": "string",
        "title": "URL",
        "default": "http://localhost:9000"
      }
    }
  }
}

我可以使用迭代格式来实现这一点,但这是不可扩展的。我已经被困了几个小时才能用递归方法得到这个。

如果我能得到一种递归方法来将此给定的 JSON 更新为javascript.

4

2 回答 2

0

我认为这可以完成。如果你看到我错过的东西,请告诉我。

// input data copied from question
const input = {
  "Coordinates": {
    "X-Coordinate": 47,
    "Y-Coordinate": -122
  },
  "Coordination Type": {
    "Cartesion Mode": false,
    "Starting Range": {
      "Start": 8000,
      "End": 9000
    }
  },
  "Map": {
    "Offline Map": false,
    "URL": "http://localhost:9000"
  }
};

// recursive field conversion function
const convertField = (key, value) => (
  {
    type: typeof value, // 'object', 'boolean', 'number', 'string'
    title: key, // field name is also the title (e.g. 'Starting Range')
    ...(
      typeof value !== 'object'
      ? { default: value } // primitive type. default and we're done
      : {  
        properties: Object.entries(value)
        .reduce((facc, [field, fvalue]) => ({
          ...facc, // keep previous iterations
          [field]: { // keep the field name, e.g. 'Starting Range',
          ...convertField(field, fvalue) // recurse for the field's value
        }
      }), {})
    }
    )
  }
  );
  
  // kick it off
  const output = Object.entries(input)
  .reduce((acc, [key, value]) => ({
    ...acc, // retain previous iteration results
    [key]: {...convertField(key, value)} // convert each property
  }), {}
  );
  
  // show the results
  document.getElementById('result').innerText = (JSON.stringify(output, null, 2))
  
<pre id="result" />

于 2019-09-07T08:24:12.170 回答
0

JSON.parsereviver 参数可用于转换值:

var json = `{
  "Coordinates": {
    "X-Coordinate": 47,
    "Y-Coordinate": -122
  },
  "Coordination Type": {
    "Cartesion Mode": false,
    "Starting Range": {
      "Start": 8000,
      "End": 9000
    }
  },
  "Map": {
    "Offline Map": false,
    "URL": "http://localhost:9000"
  }
}`

var obj = JSON.parse(json, (key, val, type = typeof val) => !key ? val : 
  { type, title: key, [type === 'object' ? 'properties' : 'default']: val } )
  
console.log(obj)

于 2019-09-07T09:29:52.650 回答