Lodash: Constructing single object from many - Merging/overriding properties

馋奶兔 提交于 2019-12-02 22:27:52

Lodash has a few methods that will help to elegantly solve this problem.

First of all, the merge method. It takes multiple source objects, and recursively merges their properties together into a destination object. If two objects have the same property name, the latter value will override the former.

This is almost what we want; it'll merge your role objects together into a single object. What we don't want is that override behavior; we want true values to always override false ones. Luckily, you can pass in a custom merge function, and lodash's merge will use that to compute the merged value when two objects have the same key.

We'll write a custom function to logically OR your items together (instead of allowing later false values to override trues.), so that if either value is true, the resulting merged value will be true.

Because our objects are nested, we'll need to make sure our custom merge function only does this OR when it's comparing boolean values. When comparing objects, we want to do a normal merge of their properties (again using our custom function to do the merge). It looks something like this:

function do_merge(roles) {

  // Custom merge function ORs together non-object values, recursively
  // calls itself on Objects.
  var merger = function (a, b) {
    if (_.isObject(a)) {
      return _.merge({}, a, b, merger);
    } else {
      return a || b;
    }
  };

  // Allow roles to be passed to _.merge as an array of arbitrary length
  var args = _.flatten([{}, roles, merger]);
  return _.merge.apply(_, args);
}

do_merge([role1, role2, role3]);

Lodash helps out in one other way: You may notice from the docs that _.merge doesn't accept an array of objects to merge together; you have to pass them in as arguments. In our case, though, an array would be awfully convenient.

To get around this, we'll use JavaScript's apply method, which allows you to invoke a method by passing its arguments as an array, and Lodash's handy flatten method, which takes an array that might contain nested arrays — like [1, [2, 3], [4, 5]] — and flattens it into [1, 2, 3, 4, 5].

So we'll gather up all the arguments we need in a flattened array, and then apply them to merge!

If your objects are nested very very deeply, there's a chance you'll overflow the stack calling merger recursively like this, but for your objects this should work just fine.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!