Skip to content

每日一题:JSON 生成器

作者:江月迟迟
发表于:2024-12-10
字数统计:1543 字
预计阅读6分钟

介绍

JSON 已经是大家必须掌握的知识点,JSON 数据格式为前后端通信带来了很大的便利。在开发中,前端开发工程师可以借助于 JSON 生成器快速构建一个 JSON 用来模拟数据。

本题请你开发一个简易的 JSON 生成器工具,使它能根据模板生成对应格式的 JSON 。

准备

开始答题前,需要先打开本题的项目代码文件夹,目录结构如下:

txt
├── css
├── index.html
└── js
    ├── highlight.min.js
    └── index.js

其中:

  • css 是样式文件夹。
  • index.html 是主页面。
  • js/highlight.min.jsjson 格式化文件。
  • js/index.js 是需要补充代码的 js 文件。

注意:打开环境后发现缺少项目代码,请手动键入下述命令进行下载:

bash
cd /home/project
wget https://labfile.oss.aliyuncs.com/courses/9788/09.zip && unzip 09.zip && rm 09.zip

在浏览器中预览 index.html 页面效果如下:

初始效果

目标

请在 index.js 文件中补全 generateData 函数代码,并最终返回一个 js 对象(说明 : generateData 生成的数据会由插件自动转化成 JSON)。

在左侧的输入框中输入指定格式的数据模板,点击生成 JSON 按钮,右侧会自动生成对应格式的 JSON 数据。

  1. 数据模板中对象的 key 对应的 value 如果是 并且符合下述规则,则根据下述规则解析,否则一律返回原始 value 值。具体规则如下:
  • {_{bool()}} 表示随机生成布尔值。
  • {_{integer(n, m)}} 表示生成 n-m 之间(包含 n、m )的随机整数(注意:n<m)。

目标1测试用例

附目标 1 测试用例:

js
{
  isPass: '{{bool()}}',
  age: '{{integer(3, 5)}}',
  goodsNumber:2,
  isShow:false,
  tag:'phone',
  fn:'{{integer}}'
}
  1. 数据模板中 {_{repeat()}}(此项只会出现在数组首位)表示重复生成数组中的数据,如:"repeat(5, 7)" 则表示随机生成 5-7 条数组数据,repeat 中值只包含一个数字,如"repeat(5)" 表示生成 5 条数组数据。

目标2测试用例

附目标 2 测试用例(3 组):

js
// (1)随机生成 `2-5` 条数组数据
[
  "{{repeat(2, 5)}}",
  {
    isActive: "{{bool()}}",
    age: "{{integer(20, 40)}}",
    num: 2,
    boolean: true,
    str: "str",
    isTel: "{{bool}}",
    fn: "{{fn()}}",
  },
]
// (2)固定生成 `7` 条数组数据
[
  ("{{repeat(7)}}",
  {
    isTrue: "{{bool()}}",
    score: "{{integer(3, 7)}}",
    tag: "android",
    isSamll: true,
    fn: "{{fn()}}",
  })
]
// (3)无 repeat 的情况
[
  { maxNum: 10 }
];

注意:本题不考虑用户输入和传参不合法的情况,只处理合法的数据格式即可,实际测试中 keyvalue 为非固定值。提供的测试用例仅为方便测试代码使用,实际使用中需要对所有符合要求的数组/对象结构的模板生效。

规定

  • 请勿修改 js/index.js 文件外的任何内容。
  • 请不要使用固定值,如对象的 key 只对测试用例的 key 生效,以免造成无法判题通过。
  • 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径、class 名、id 名、图片名等,以免造成无法判题通过。

判分标准

  • 实现目标 1,得 10 分。
  • 实现目标 2,得 15 分。

总通过次数: 280 | 总提交次数: 348 | 通过率: 80.5%

难度: 中等 标签: 2022, 国赛, Web 前端, JavaScript

题解

js
/*
 * @param {*}  左侧输入框输入的值转化成的 js 数据
 * @return {*} 根据传入的数据生成对应的 js 格式数据
 */
let generateData = (data) => {
  // TODO:待补充代码
  const reg1 = /^\{\{repeat\([\d,\s]+\)\}\}/
  const reg2 = /^\{\{bool\(\)\}\}$/
  const reg3 = /^\{\{integer\([\d,\s]+\)\}\}$/
  if (!Array.isArray(data)) {
    // 是对象
    for(let key in data) {
      if (reg2.test(data[key]) || reg3.test(data[key])) {
        data[key] = eval(data[key])
      }
    }
    return data
  }
  let len = reg1.test(data[0]) ? eval(data[0]) : 1
  let result = []
  while (result.length !== len) {
    let obj = {...data[1]}
    for(let key in obj) {
      if (reg2.test(obj[key]) || reg3.test(obj[key])) {
        obj[key] = eval(obj[key])
      }
    }
    result.push(obj)
  }

  function repeat(a,b) {
    return b ? Math.random() * (b - a + 1) + a | 0 : a
  }
  function integer(a,b) {
    return Math.random() * (b - a + 1) + a | 0
  }
  function bool() {
    return Math.random() < 0.5
  }
  return result
};

module.exports = { generateData };
/*
 * @param {*}  左侧输入框输入的值转化成的 js 数据
 * @return {*} 根据传入的数据生成对应的 js 格式数据
 */
let generateData = (data) => {
  // TODO:待补充代码
  const reg1 = /^\{\{repeat\([\d,\s]+\)\}\}/
  const reg2 = /^\{\{bool\(\)\}\}$/
  const reg3 = /^\{\{integer\([\d,\s]+\)\}\}$/
  if (!Array.isArray(data)) {
    // 是对象
    for(let key in data) {
      if (reg2.test(data[key]) || reg3.test(data[key])) {
        data[key] = eval(data[key])
      }
    }
    return data
  }
  let len = reg1.test(data[0]) ? eval(data[0]) : 1
  let result = []
  while (result.length !== len) {
    let obj = {...data[1]}
    for(let key in obj) {
      if (reg2.test(obj[key]) || reg3.test(obj[key])) {
        obj[key] = eval(obj[key])
      }
    }
    result.push(obj)
  }

  function repeat(a,b) {
    return b ? Math.random() * (b - a + 1) + a | 0 : a
  }
  function integer(a,b) {
    return Math.random() * (b - a + 1) + a | 0
  }
  function bool() {
    return Math.random() < 0.5
  }
  return result
};

module.exports = { generateData };

题解2

js
/*
 * @param {*}  左侧输入框输入的值转化成的 js 数据
 * @return {*} 根据传入的数据生成对应的 js 格式数据
 */

let reg1 = /^\{\{bool\(\)\}\}$/
let reg2 = /^\{\{integer\([\d,\s]+\)\}\}$/
let reg3 = /^\{\{repeat\([\d,\s]+\)\}\}$/

function bool() {
  return Math.random() < 0.5
}

function integer(a,b) {
  return Math.floor(Math.random() * (b - a + 1) + a)
}

function repeat(a,b) {
  return b ? Math.floor(Math.random() * (b - a + 1) + a) : a
}

let genObj = (data) => {
  // return an obj
  for(let key in data) {
    if(reg1.test(data[key]) || reg2.test(data[key])) {
      // replace template
      data[key] = eval(data[key])
    }
  }
  return data
}

let generateData = (data) => {
  // TODO:待补充代码
  let result
  if(Array.isArray(data)){
    // is array
    // judge array[0] is a template
    if(reg3.test(data[0])) {
      // array[0] is a template
      // get length of array
      let len = eval(data[0])
      result = []
      for(let i = 0; i < len; i++) {
        result.push(genObj(data[1]))
      }
    } else {
      // is obj in array
      result = [genObj(data[0])]
    }
  } else {
    // is obj
    result = genObj(data)
  }
  return result
};

module.exports = { generateData };