javascript - 当对象值与其他对象相同时如何覆盖特定值
问题描述
https://jsfiddle.net/JungEun1997/nb3o1987/50/
我已经达到了预期的结果,但您希望以更简单的方式查看它。我尝试使用地图和过滤器但失败了。
我想以更简单的方式将此 obj_wrap 更改为 obj_a !(start_num和end_num相差 1)
var obj_wrap = {
'time':[{
'start_num': 10,
'end_num':11
},{
'start_num': 3,
'end_num':4
},{
'start_num': 1,
'end_num':2
},{
'start_num': 2,
'end_num':3
},{
'start_num': 6,
'end_num':7
}]
}
var obj_a = {
'time':[{
'start_num': 1,
'end_num':4
},{
'start_num': 6,
'end_num':7
},{
'start_num': 10,
'end_num':11
}]
}
我用了这个方法。
var obj_b = {'time':[]}
$.each(obj_wrap.time,function(time_key,time_val){
$.each(obj_wrap.time,function(chk_key,chk_val){
if(time_val.start_num === chk_val.end_num){
obj_wrap.time[time_key]['start_num'] = chk_val.start_num
obj_wrap.time[chk_key] = ""
}
if(time_val.end_num === chk_val.start_num){
obj_wrap.time[time_key]['end_num'] = chk_val.end_num
obj_wrap.time[chk_key] = ""
}
});
})
$.each(obj_wrap.time,function(key,value){
if(value!==""){
obj_b.time.push(value)
}
})
obj_b.time.sort(function (a, b) {
return a.start_num < b.start_num ? -1 : a.start_num > b.start_num ? 1 : 0;
});
解决方案
我已经实现了一个简单的数据记忆缓存,其中键值对表示start_num
&end_num
值(参见代码注释以获得视觉效果)。
创建备忘录后,您可以在线性时间内迭代备忘录,并相应地填充结果数组。对于那部分,我选择了reduce
,因为它保留了一个可用于每次迭代的瞬态。
在每次迭代中,我基本上只是检查是否应该在不填充times
数组的情况下继续迭代。一旦我检测到数字链中的中断,就会在times
使用预期结果填充数组之前进行一些边缘情况检查。
时间和空间复杂度为 O(n)。
const objWrap = {
time:[{
start_num: 10,
end_num:11
}, {
start_num: 3,
end_num:4
}, {
start_num: 1,
end_num:2
}, {
start_num: 2,
end_num:3
}, {
start_num: 6,
end_num:7
}],
};
const memo = objWrap.time.reduce((acc, next) => {
if (!Reflect.has(acc, next.start_num)) {
acc[next.start_num] = next.end_num;
}
return acc;
}, {});
/*
memo is now:
{
1: 2,
2: 3,
3: 4,
6: 7,
10: 11
}
NOTE: If you store key's as numbers in a JS object, they'll be automatically sorted.
*/
const entries = Object.entries(memo);
const result = entries
.slice(1) // iterate across all entries except the first since we'll use the first entry to initialize our accumulator.
.reduce((acc, [start,end], i, arr) => {
if (Reflect.has(memo, acc.next)) { // if we found a sequence, then just continue iterating.
acc.next = end;
} else {
acc.times.push({ // if the sequence is broken, then we have a result.
start_num: Number(acc.start), // cast back to number, as it's currently a string
end_num: acc.next,
});
if (i === arr.length - 1) { // if we've reached the end of the array, then prepare the last result as well.
acc.times.push({
start_num: Number(start),
start_end: end,
});
delete acc.next;
delete acc.start;
} else { // if we haven't reached the end of the array, then prepare the next iteration's comparison.
acc.start = start;
acc.next = end;
}
}
return acc;
}, {
next: entries[0][1], // initialize accumulator with first entryies end value.
start: entries[0][0], // initialize accumulator with first entryies start value.
times: [],
});
console.log(JSON.stringify(result, null, 2))
推荐阅读
- cocoapods - 如何下载带有 cocoapods 的 Mapbox iOS SDK 6.0 及更高版本
- javascript - 程序忽略异步模式
- faunadb - 如何按创建的时间戳搜索和排序动物区系数据库
- java - Socket.close 卡住了 15 分钟
- c# - 通过 key -updated 查找键值对列表的索引
- node.js - 如何解决发布请求失败 ReactJS 和 ExpressJS
- javascript - 检查对象数组范围内的日期
- azure - 是否可以在事件发生时自动将所有用户从 Azure Active Directory 转移到另一个域数据库?
- mongodb - 查找嵌套数组至少包含两个特定子文档的所有文档
- virtual-machine - VirtualBox没有IP地址使用内部网络