33

数据结构

功能是实现历史记录的数据添加,数据按年月日组织如下:

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
"timeData": {
"2019": { //年
"11": { //月
"12": [ //日
{
"start": "21:14",
"end": "21:25",
"duration": "0:11"
},
{
"start": "23:34",
"end": "23:45",
"duration": "0:11"
}
],
"13": [
{
"start": "23:34",
"end": "23:45",
"duration": "0:11"
}
]
}
}
}

if else实现

添加时需要考虑没有对应年月日的情况,初次通过if else嵌套实现如下:

原理是依次尝试按指定日、月、年去获取数据,有数据则说明该日期以存在,该日没有则查月,月没有则查年,年没有则添加该年月日,有年无月则添加该月日,有月无日则添加该日。

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
let dbData = getData(start.slice(0, 10)) //取指定年月日数据
if (dbData) {
dbData.push(data)
save()
} else {
dbData = getData(start.slice(0, 7)) //取指定年月数据
log('dbData', dbData)
if (dbData) {
dbData[sD] = [data]
save()
} else {
dbData = getData(start.slice(0, 4)) //取指定年数据
log('dbData', dbData)
if (dbData) {
dbData[sM] = { [sD]: [data] }
save()
} else {
dbData = getData(start.slice(0, 0)) //取数据对象
log('dbData', dbData)
if (dbData) {
dbData[sY] = { [sM]: { [sD]: [data] } }
save()
} else {
log('Error: addTime startdata error')
}
}
}
}

可以看到if else嵌套方式可读性较差,各级相似很难一眼看懂逻辑。

switch实现

下面通过dbData的“或”赋值和gData函数,减少冗余代码并巧妙的定位数据情况(location),并结合switch语句根据数据情况进行处理:

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
let location: number = 0  
let [ymd, ym, y] = [10, 7, 4] //ymd代表年月日的字符数,如: 2019-04-20 为10
let dbData = gData(ymd) || gData(ym) || gData(y) || gData(0) //依次按日,月,年查找数据, 有则赋值
function gData(i: number) {
location = i //用于定位数据提取的级别
return getData(start.slice(0, i))
}

//根据数据的级别添加数据, 比如有年无月,则添加月日数据
switch (location) {
case ymd:
dbData.push(data)
save()
break
case ym:
dbData[sD] = [data]
save()
break
case y:
dbData[sM] = { [sD]: [data] }
save()
break
case 0:
dbData[sY] = { [sM]: { [sD]: [data] } }
save()
break
default:
log('Error: addTime startdata error')
break
}

对象字面量实现

过了一天看到switch语句可用对象字面量替代,能大大降低圈复杂度,便将已上代码简化如下:

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
function addTime(start: string[], end: string[]) {
log('start', start, 'end', end)
let [sY, sM, sD, sT] = start //时间转数组['2019','04','20','06:20']
let [eY, eM, eD, eT] = end
let data = {
start: sT,
end: eT,
duration: parseInt(eT) - parseInt(sT) + ':' + (parseInt(eT.slice(3)) - parseInt(sT.slice(3))),
}
log('data', data)

//以下为简化的地方
let location: number = 0
let [d, m, y] = [3, 2, 1] //取到 日,月,年 的数组项数量,如 d:['2019','04','20']
let dbData = gData(d) || gData(m) || gData(y) || gData(0) //依次按日,月,年查找数据, 有则赋值
function gData(i: number) {
location = i //用于定位数据提取的级别
return getData(start.slice(0, i)) //通过日期查找对应的年月日数据
}
log('dbData', dbData, 'location', location)

//根据已有的日期的情况添加数据, 比如有年无月,则添加月日数据
let situation = {
[d]: () => dbData.push(data),
[m]: () => (dbData[sD] = [data]),
[y]: () => (dbData[sM] = { [sD]: [data] }),
0: () => (dbData[sY] = { [sM]: { [sD]: [data] } }),
}
situation[location]()
save()
}

原文发布自:有度博客