首页 > 解决方案 > 当对象值与其他对象相同时如何覆盖特定值

问题描述

https://jsfiddle.net/JungEun1997/nb3o1987/50/

我已经达到了预期的结果,但您希望以更简单的方式查看它。我尝试使用地图过滤器但失败了。

我想以更简单的方式将此 obj_wrap 更改为 obj_a !(start_numend_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;  
});

标签: javascriptjqueryobject

解决方案


我已经实现了一个简单的数据记忆缓存,其中键值对表示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))


推荐阅读