Lodash。智能通过键合并两个对象

时间:2017-08-02 10:14:35

标签: javascript lodash

我有两个对象。 A和B.

A

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

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

如何循环A键,将其与B对象进行比较,并通过Lodash更新A对象中现有键的值?也许存在一些不错的方式?我尝试使用“assing,assignWith”,但看起来我还不明白它是如何工作的。

结果应该是这样的:

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

感谢您提供任何信息。

我已经通过原生js解决了这个问题,但我想知道如何通过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);
}

5 个答案:

答案 0 :(得分:6)

您可以使用_.mergeWith lodash方法并传递自定义函数。

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.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

答案 1 :(得分:1)

这样可以解决问题,请注意结果将使所有密钥具有相同的value, error格式

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.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

答案 2 :(得分:1)

这是一个迭代B阵列并使用set更新值的解决方案:

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

答案 3 :(得分:0)

从第二个对象映射y以相应地更新第一个对象:

&#13;
&#13;
_keys
&#13;
// 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);
&#13;
&#13;
&#13;

更新:我会使用@GruffBunny的解决方案 - 这个想法与此类似,但使用lodash做得更优雅。

答案 4 :(得分:0)

您可以使用lodash#mergelodash#mapValues来实现此目标。

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

&#13;
&#13;
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);
&#13;
.as-console-wrapper { min-height: 100%; top: 0; }
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
&#13;
&#13;
&#13;