替换对象中的嵌套字段值

时间:2020-01-12 20:03:55

标签: javascript

我需要将嵌套对象中的每个time值替换为其值的momentJS元素。

const input = {
  data: {
    sub1: {
      time: 1578857603218
    }
    sub2: {
      some: 'thing,
      foo: [{
        value: 123,
        time: 1578857603218
      }]
    }
  }
}

现在我的代码看起来非常丑陋,因为我手动执行此操作,因为某些字段具有可选的时间值。

if (data && data.sub2 && data.sub2.foo && data.sub2.foo[0].time) {
  data.sub2.foo[0].time = moment(data.sub2.foo[0].time).toDate()
}

要以更动态的方式执行此操作,我看到两个选项:

  1. 传递带有所有可选时间字段的数组/映射之类的东西,并用循环替换它们

是否有更好的方法来替换我的if条件来遍历所有更换时间字段?

  1. 遍历所有键

但这不适用于嵌套对象。

for (var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
        // do stuff
    }
}

4 个答案:

答案 0 :(得分:0)

每当您要处理深度不确定的嵌套对象时,请考虑递归

const setTime = (object, time) => {
  for (let prop in object) {
    if (!Object.prototype.hasOwnProperty.call(object, prop)) {
       continue;
    }
    if (typeof (object[prop]) === 'object') {
      setTime(object[prop], time);
    }
    if (prop === 'time') {
      object.time = time;
    }
  }
  return object;
};

const input = {
  data: {
    sub1: {
      time: 1578857603218
    },
    sub2: {
      some: 'thing',
      foo: [{
        value: 123,
        time: 1578857603218
      }]
    }
  }
}

setTime(input, 666);

答案 1 :(得分:0)

尝试一下:)秘密就是递归循环

const input = {
  data: {
    sub1: {
      time: 1578857603218
    },
    sub2: {
      some: 'thing',
      foo: [{
        value: 123,
        time: 1578857603218
      }]
    }
  }
};


function changeTime(obj) {
  obj && Object.keys(obj).forEach(key => {
     if(key === 'time') {
       obj.time = moment(obj.time); // you have to use moment
     }

     if(typeof obj[key] === 'object'){
       changeTime(obj[key]);
     }
   });
}

changeTime(input);
console.log(input);

答案 2 :(得分:0)

如果您知道键值对,那么显示为已在使用中的正是您应使用的。它是O(1),非常快,基本上是一行。

要使该动态变化需要O(n),其中n是键值对的数量,并且需要几行代码。

const renderTime = input => {
  if (Array.isArray(input)) {
    input.forEach(el => renderTime(el));
  }
  if (typeof input === 'object' && !!input) {
    Object.keys(input).forEach(k => {
      if (k === 'time') input[k] = 'moment(input[k]).toDate()';
      else renderTime(input[k]);
    });
  }
};

const input = {
  data: {
    sub1: {
      time: 1578857603218
    },
    sub2: {
      some: 'thing',
      foo: [{
        value: 123,
        time: 1578857603218
      }]
    }
  }
};

renderTime(input);
console.log(input);

答案 3 :(得分:0)

这不会处理嵌套字段在数组中的情况,但它应该适用于嵌套对象

function replaceNestedValues(obj, targetVal, nextVal) {
  return Object.keys(obj).reduce((acc, key) => {
    const value = obj[key];
    if (typeof value === 'object' && value !== null) {
      acc[key] = replaceNestedValues(value, targetVal, nextVal);
    } else if (value === targetVal) {
      acc[key] = nextVal;
    } else {
      acc[key] = value;
    }
    return acc;
  }, {});
}

示例

const data = { a: { b: 10, c: null }, d: null };
replaceNestedValues(data, null, '');
// => { a: { b: 10, c: '' }, d: '' }