【问题标题】:Deep Replace values in one object with another object - javascript用另一个对象深度替换一个对象中的值 - javascript
【发布时间】:2018-04-14 12:38:24
【问题描述】:

您好,我正在使用 javascript/node.js。我有两个数据对象。 (请注意,真实的物体比这复杂得多。)

    const original = {
        'totAmount': 10,
        'testVal': 'zzzzzzzz',
        'potentialPaid': 10,
        'depositAmount': 10,
        'payment': {
            'amount': 10,
             'testVal': 'zzzzzzzz',
            'details': {
                'amount': 10,
                'testVal': 'zzzzzzzz',
                'statusHistory': {
                    'amount': 10,
                    'testVal': 'zzzzzzzz'
                }
            }
        },
        'coupon': {'test': 1000}
    };

const dataToUpdate = {
        'totAmount': 65,
        'potentialPaid': 65,
        'depositAmount': 65,
        'payment': {
            'amount': 65,
            'details': {
                'amount': 65,
                'statusHistory': {
                    'amount': 65
                }
            }
        },
        'coupon': {}
    };

我想用相同的键替换 dataToUpdate 中的 original 中的所有值。

我的预期结果是

    const original = {
        'totAmount': 65,
        'testVal': 'zzzzzzzz',
        'potentialPaid': 65,
        'depositAmount': 65,
        'payment': {
            'amount': 65,
            'testVal': 'zzzzzzzz',
            'details': {
                'amount': 65,
                 'testVal': 'zzzzzzzz',
                'statusHistory': {
                    'amount': 65,
                    'testVal': 'zzzzzzzzz
                }
            }
        },
        'coupon': {}
    };
  • 原始对象中具有相同键的所有值都应替换为其他对象值。

我正在研究各种解决方案,例如 Object.assign() .merge in lodash 和许多其他解决方案。

我已经坚持了 3 个多小时,但我仍然找不到任何解决方案。

有没有可以做这种事情的默认javascript函数? , 请帮忙。

提前致谢。

【问题讨论】:

  • 我认为您正在尝试同时合并具有两个不同条件的两个对象。我的意思是,您试图将 original.payment.testVal 保留在结果对象中,然后您想在结果对象中省略 original.coupon.test。那么,您的辅助函数(Object.assign、_.merge 等)如何知道何时要保留原始对象中的字段以及何时不保留?
  • mm 我想如果对象为空我想替换,如果对象不为空我想合并
  • 我不知道有一个函数(无论是本机的还是来自库的)可以帮助您实现这一目标,因为您正在应用自定义标准。如果可以,您将需要实现自己的合并功能。

标签: javascript node.js loops object lodash


【解决方案1】:

经过一番研究,我发现自 4.0.0 版以来,lodash 有一个 mergeWith 函数,可让您为合并应用自定义条件。

我在这里添加了一个适用于您的示例的 jsfiddle,但可能需要稍微调整以涵盖其他一些场景(但我不确定)。

jsfiddle 中可以让您自定义合并条件的函数是这样的:

function customizer(objValue, srcValue) {
  if (_.isEmpty(srcValue)) {
    return srcValue;
  }
  else {
    _.merge(objValue, srcValue);
  }
}

这里是 jsfiddle:

http://jsfiddle.net/q9g2L60g/

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    Lodash 的 _.mergeWith() 是开箱即用的递归。 _.mergeWith() 接受定制器功能。如果定制器返回undefined_.mergeWith() 使用它的默认合并规则。

    const original = {"totAmount":10,"testVal":"zzzzzzzz","potentialPaid":10,"depositAmount":10,"payment":{"amount":10,"testVal":"zzzzzzzz","details":{"amount":10,"testVal":"zzzzzzzz","statusHistory":{"amount":10,"testVal":"zzzzzzzz"}}},"coupon":{"test":1000}};
    const dataToUpdate = {"totAmount":65,"potentialPaid":65,"depositAmount":65,"payment":{"amount":65,"details":{"amount":65,"statusHistory":{"amount":65}}},"coupon":{}};
    
    const result = _.mergeWith(original, dataToUpdate, (objValue, srcValue) => _.isEmpty(srcValue) ? srcValue : undefined);
    
    console.log(result);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

    【讨论】:

      【解决方案3】:

      我做了一个自定义函数来替换对象中的嵌套属性,包括数组、对象和日期。

      const a = {
        name: 'John Doe',
        email: 'john@mail.com',
        location: {
          country: {
            name: 'Japan',
            abbr: 'JP',
          },
          place: 'Tokyo',
        },
        phone: [123, 456],
        age: new Date('2021-05-15T15:28:37.453Z'),
      };
      
      const b = {
        email: 'johndoe@mail.com',
        location: {
          country: {
            name: 'Canada',
            abbr: 'CA',
          },
        },
        phone: [123],
        age: new Date('2001-08-15T15:28:37.453Z'),
      };
      
      const superReplace = (object, value) => {
        let replace = {};
      
        Object.keys(object).forEach(prop => {
          if (value[prop] !== undefined) {
            if (Array.isArray(object[prop])) replace[prop] = value[prop];
            else if (value[prop] instanceof Date) {
              replace[prop] = value[prop];
            } else if (typeof object[prop] === 'object' && object[prop] !== null) {
              replace[prop] = superReplace(object[prop], value[prop]);
            } else replace[prop] = value[prop];
          } else replace[prop] = object[prop];
        });
      
        return replace;
      };
      
      console.log(superReplace(a, b));
      // {
      //   name: 'John Doe',
      //   email: 'johndoe@mail.com',
      //   location: { country: { name: 'Canada', abbr: 'CA' }, place: 'Tokyo' },
      //   phone: [ 123 ],
      //   age: 2001-08-15T15:28:37.453Z
      // }
      

      【讨论】:

        猜你喜欢
        • 2012-12-05
        • 1970-01-01
        • 1970-01-01
        • 2015-03-31
        • 1970-01-01
        • 1970-01-01
        • 2015-09-22
        • 1970-01-01
        • 2023-03-03
        相关资源
        最近更新 更多