【问题标题】:How to override specific value when object value is same as other object当对象值与其他对象相同时如何覆盖特定值
【发布时间】:2019-12-05 00:13:07
【问题描述】:

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

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

我想以更简单的方式将这个 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;  
});

【问题讨论】:

  • 你想通过递增顺序链接end_nums吗?
  • 您想在结果中包含空的/无意义的对象吗?因为你现在要推{ "start_num": "", "end_num": "" }, 两次。

标签: javascript jquery object


【解决方案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 time = obj_wrap.time;
var bucket = [];

time.forEach(({start_num, end_num}) => {
    for (var i = start_num; i < end_num; i++) {
        bucket[i] = true;
    }
});

var newTime = [];

bucket.forEach((_, index) => {
    if (bucket[index - 1]) {
        newTime[newTime.length - 1].end_num = index + 1;
    } else {
        newTime.push({start_num: index, end_num: index + 1});
    }
});

var obj_a = {time: newTime};

console.log(obj_a);

复杂度是O(n)

【讨论】:

    【解决方案2】:

    我已经实现了一个简单的数据记忆缓存,其中键值对代表start_numend_num 值(请参阅代码 cmets 以获得视觉效果)。

    创建备忘录后,您可以在线性时间内迭代备忘录,并相应地填充结果数组。对于这部分,我选择了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))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-09
      • 1970-01-01
      • 2017-06-09
      • 2018-08-11
      • 1970-01-01
      相关资源
      最近更新 更多