Lodash. Умное слияние двух объектов по ключам

1

У меня есть два объекта. A и B.

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

В

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

Как мне выполнить цикл через клавиши A, сравнить его с объектом B и обновить значения существующих ключей в объекте A через Lodash? Может быть, есть хороший способ? Я попытался использовать "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);
}
  • 0
    Вы знаете, что Lodash полностью написан на JS? Если вы можете сделать это с помощью vanilla JS, зачем вводить другую библиотеку, чтобы выполнить то же самое?
  • 0
    Да, я знаю, очевидно. Но я хочу знать, как решить эту задачу с помощью Lodash.
Теги:
lodash

5 ответов

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>
  • 0
    Что если b содержит ключ "mozes"?
  • 0
    @ Понятно, обновил мой ответ.
Показать ещё 1 комментарий
1

Здесь решение, которое выполняет итерацию по массиву B и использует set для обновления значения:

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

Это будет делать трюк, обратите внимание, что результат будет иметь все ключи в одном value, error формат 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>
  • 0
    Люблю это, но что произойдет, если значение B ложно (например, 0 )
  • 0
    Вы всегда можете уточнить условие B[key] || value.value зависимости от вашего B[key] || value.value использования - поддерживаете ли вы ложные значения?
Показать ещё 1 комментарий
0

Для этого вы можете использовать lodash#merge и lodash#mapValues.

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

_keys через _keys из вашего второго объекта, чтобы соответственно обновить первый объект:

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

Обновление: я бы использовал решение от @GruffBunny - идея похожа на эту, но сделана гораздо более элегантно, используя lodash.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню