最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Lodash. Smart merge two objects by keys - Stack Overflow

programmeradmin0浏览0评论

I have the two objects. A and B.

A

{
   "beta" : {
     "value": null,
     "error" : null
   },
   "hamma" : {
     "value": null,
     "error" : null
   },
   "zerta" : {
     "value": null,
     "error" : null
   },
   "mozes" : 5
}

B

{
   "beta" : 5,
   "hamma" : 2
}

How do I can loop through the A keys, pare it with the B object and update the values of the existing keys in the A object via Lodash? Maybe there is exists some nice way? I tried to use "assing, assignWith" but looks like I haven't understood how it works.

The result should looks like that:

{
   "beta" : {
     "value": 5,
     "error" : null
   },
   "hamma" : {
     "value": 2,
     "error" : null
   },
   "zerta" : {
     "value": null,
     "error" : null
   },
   "mozes" : 5
}

Thanks for any information.

I have resolved this solution via native js by that way but I want to know how can I do it via Lodash.

export function mapServerModelToStateValues(state, serverModel) {
    let updatedState = {};
    const serverModelKeyList = Object.keys(serverModel);

    Object.keys(state).forEach(stateKey => {

        serverModelKeyList.forEach(modelKey => {
            if ( modelKey === stateKey ) {
                updatedState[ stateKey ] = {
                    ...state[ stateKey ],
                    value : serverModel[ modelKey ]
                }
            }
        });
    });

    console.log(updatedState);
}

I have the two objects. A and B.

A

{
   "beta" : {
     "value": null,
     "error" : null
   },
   "hamma" : {
     "value": null,
     "error" : null
   },
   "zerta" : {
     "value": null,
     "error" : null
   },
   "mozes" : 5
}

B

{
   "beta" : 5,
   "hamma" : 2
}

How do I can loop through the A keys, pare it with the B object and update the values of the existing keys in the A object via Lodash? Maybe there is exists some nice way? I tried to use "assing, assignWith" but looks like I haven't understood how it works.

The result should looks like that:

{
   "beta" : {
     "value": 5,
     "error" : null
   },
   "hamma" : {
     "value": 2,
     "error" : null
   },
   "zerta" : {
     "value": null,
     "error" : null
   },
   "mozes" : 5
}

Thanks for any information.

I have resolved this solution via native js by that way but I want to know how can I do it via Lodash.

export function mapServerModelToStateValues(state, serverModel) {
    let updatedState = {};
    const serverModelKeyList = Object.keys(serverModel);

    Object.keys(state).forEach(stateKey => {

        serverModelKeyList.forEach(modelKey => {
            if ( modelKey === stateKey ) {
                updatedState[ stateKey ] = {
                    ...state[ stateKey ],
                    value : serverModel[ modelKey ]
                }
            }
        });
    });

    console.log(updatedState);
}
Share Improve this question edited Aug 2, 2017 at 10:39 Phil 165k25 gold badges262 silver badges267 bronze badges asked Aug 2, 2017 at 10:14 VelidanVelidan 6,04414 gold badges57 silver badges93 bronze badges 2
  • You know Lodash is pletely written in JS? If you can do it with vanilla JS, why bother introducing another library to acplish the same thing? – Phil Commented Aug 2, 2017 at 10:28
  • Yes, I know, obviously. But I want to know how to resolve this task by Lodash using. – Velidan Commented Aug 3, 2017 at 7:55
Add a ment  | 

5 Answers 5

Reset to default 6

You can use _.mergeWith lodash method and pass custom function.

var a = {"beta":{"value":null,"error":null},"hamma":{"value":null,"error":null},"zerta":{"value":null,"error":null},"mozes":5}

var b = {"beta":5,"hamma":2, "mozes": 123}

_.mergeWith(a, b, function(aValue, bValue) {
  _.isPlainObject(aValue) ? aValue.value = bValue : aValue = bValue
  return aValue
})

console.log(a)
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Here's a solution that iterates over the B array and uses set to update the value:

_.each(updates, (value, key) => _.set(data, `${key}.value`, value))

This will do the trick, notice that the result will have all the keys in the same value, error format

const A = {
  "beta": {
    "value": null,
    "error": null
  },
  "hamma": {
    "value": null,
    "error": null
  },
  "zerta": {
    "value": null,
    "error": null
  },
  "mozes": 5
}
const B = {
  "beta": 5,
  "hamma": 2
}

const C = _.mapValues(A, (value, key) => {
  return {
    ...value,
    value: B[key] || value.value
  }
});

console.log(C)
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Map through the _keys from your second object to update the first object accordingly:

// obj a
const a = {
  beta: {
    value: null,
    error: null
  },
  hamma: {
    value: null,
    error: null
  },
  zerta: {
    value: null,
    error: null
  },
  mozes: 5
};

// obj b
const b = {
  beta: 5,
  hamma: 2
};

// map through the 'obj b' keys and update 'obj a' accordingly
_.keys(b).map(key => {
  a[key].value = b[key];
});


// log obj a to the console
console.log(a);
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Update: I would use the solution from @GruffBunny - the idea is similar to this one, but done much more elegantly using lodash.

You can use lodash#merge and lodash#mapValues to achieve this.

var result = _.merge({}, a, _.mapValues(b, value => ({ value })));

var a = {
   "beta" : {
     "value": null,
     "error" : null
   },
   "hamma" : {
     "value": null,
     "error" : null
   },
   "zerta" : {
     "value": null,
     "error" : null
   },
   "mozes" : 5
};

var b = {
   "beta" : 5,
   "hamma" : 2
};

var result = _.merge({}, a, _.mapValues(b, value => ({ value })));
  
console.log(result);
.as-console-wrapper { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

发布评论

评论列表(0)

  1. 暂无评论