-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
emmm...这个题目不太对,普通的时间旅行对象需要做的只是,去记录对象被修改的过程,然后根据需求把不同时刻修改的对象取出来再用就行了。
经常我们会遇到一个场景,去把一个含有不同维度的数组降维处理,从而更加方便的去遍历数组得到自己想要的数据。
代码如下:
class FlatArray {
constructor(targetArr) {
this.resultArr = targetArr
// 循环判断目标数组中是否还有成员是数组
while (this.resultArr.some(item => Array.isArray(item))) {
this.operation()
}
}
operation() {
// 将数组展开
this.resultArr = [].concat(...this.resultArr)
}
get() {
return this.resultArr
}
}
const test = new FlatArray([1, 2, [3, 4, [5, 6]], [7, 8], 9])
console.log(test.get())这段代码比较简单,所以不多做解释了,重点就是通过 concat 和数组扩展进行组合。那么来谈谈我们今天要做任务之一吧,去组装一个对象,换句话说是将对象升维。举一个简单的例子:
有这样一个字符串 'hello',我们要做的是将其处理成
{
h: {
e: {
l: {
l: {
o: 'target'
}
}
}
}
}任务之二是 将这个对象变成可以时间旅行的,即每次 set 操作都会把原来的对象记录下来并且可查询。
分析任务一
任务一的核心是怎么将字符串的每个字符关联起来,并且能够依次有一一对应的关系,简单的分析就知道应该使用 reduce 来做,代码如下:
set(path, value) {
// to be implemented
let target = Object.create(null);
let pathArr = path.split("."); // 转换成数组
let len = pathArr.length;
// 将每个成员转化成对象,并且依次关联
let targetObj = pathArr
.map(item => {
let nullObject = Object.create(null);
nullObject[item] = item;
return nullObject;
})
.reverse()
.reduce((prev, next, index) => {
// operation
});
}接下来只需要考虑:最后一个元素的 key 对应的 value 是由参数决定;后一个字符为前一个字符的 key 值这两种情况就行了,处理代码为:
if (index === 1) {
prev[pathArr[len - 1]] = value;
}
next[pathArr[len - 1 - index]] = prev;
return next;大功告成!我们已经成功的将字符串转化成了一个多层的对象~
分析任务二:
我们需要做的很简单,即每次进行 set 操作的时候给对象加一个时间戳即可。
get(time) {
// to be implemented
if (time) {
let i = 0;
if (this.history.length > 1) {
this.history.some((item, index) => {
if (item.time > time) {
i = index - 1;
return true;
}
return false
});
return this.history[i].data;
}
}
return this.object;
}整个下来的代码就是:
class TimeTravelObject {
constructor() {
this.object = Object.create(null);
this.history = [];
}
get(time) {
// to be implemented
if (time) {
let i = 0;
if (this.history.length > 1) {
this.history.some((item, index) => {
if (item.time > time) {
i = index - 1;
return true;
}
});
return this.history[i].data;
}
}
return this.object;
}
set(path, value) {
// to be implemented
let target = Object.create(null);
let pathArr = path.split(".");
let len = pathArr.length;
let targetObj = pathArr
.map(item => {
let nullObject = Object.create(null);
nullObject[item] = item;
return nullObject;
})
.reverse()
.reduce((prev, next, index) => {
if (index === 1) {
prev[pathArr[len - 1]] = value;
}
next[pathArr[len - 1 - index]] = prev;
return next;
});
const now = Date.now();
this.object = targetObj;
this.history.push({
time: now,
data: targetObj
});
}
}emmm….写完这些大概花了 40 分钟,还是花了太久了,主要的时间就是花在如何去更好的依次关联字符串的字符,让它们依次嵌套。。。
说下后来,又经过启发想到的实现方法,可以通过字符串正则匹配,将其处理成 JSON.stringify的形式,然后 parse成目标对象,我觉得这样效率和性能上肯定是远远超过我上面的时间方法,要是有时间也去尝试一下这种做法。