每日一题:JSON 生成器

介绍

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

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

准备

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

1
2
3
4
5
├── css
├── index.html
└── js
├── highlight.min.js
└── index.js

其中:

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

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

1
2
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 测试用例:

1
2
3
4
5
6
7
8
{
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 组):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// (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

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
* @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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/*
* @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 };