Как объединить два объекта, переопределяя нулевые значения? - PullRequest
0 голосов
/ 17 мая 2019

Я хотел бы объединить два похожих, но не идентичных объекта и переопределить нулевые значения в одном из них, если таковые существуют. Например, у меня есть эти два объекта:

const obj1 = {
    a: 1,
    b: '',
    c: [],
    d: null
}

const obj2 = {
    a: 2,
    b: null,
    d: 1
}

И эффект слияния должен быть:

const objMerged = {
    a: 2,
    b: '',
    c: [],
    d: 1
}

Другими словами, наиболее важным источником данных в объединенном объекте является obj2, но ему не хватает некоторых свойств из obj1, поэтому их необходимо скопировать, а также некоторые из значений obj2 равны null поэтому они должны быть взяты из obj1.

EDIT Я попробовал:

_.extend({}, obj1, obj2) 

и

Object.assign({}, obj1, obj2)

Ответы [ 7 ]

2 голосов
/ 17 мая 2019

Вы также можете смешивать и сочетать с ES6 деструктуры и lodash _.omitBy:

const obj1 = { a: 1, b: '', c: [], d: null }
const obj2 = { a: 2, b: null, d: 1 }

const result = {..._.omitBy(obj1, _.isNull), ..._.omitBy(obj2, _.isNull)}

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

Вы также можете сделать это с ES6 только так:

const obj1 = { a: 1, b: '', c: [], d: null }
const obj2 = { a: 2, b: null, d: 1 }

let omitNull = obj => {
  Object.keys(obj).filter(k => obj[k] === null).forEach(k => delete(obj[k]))
  return obj
}

const result = { ...omitNull(obj1), ...omitNull(obj2) }

console.log(result)
1 голос
/ 17 мая 2019
var objMerged  = {};
for (var kobj1 in obj1) {
    for (var kobj2 in obj2) {
        if (obj1[kobj1] == null && obj2[kobj1] != null)
            objMerged[kobj1] = obj2[kobj1];
        else if (obj2[kobj2] == null && obj1[kobj2] != null)
            objMerged[kobj2] = obj1[kobj2];

    }
}

// Печать objMerged для отображения

1 голос
/ 17 мая 2019

Вот решение на основе чистого JS:

Выполните итерацию по первому объекту для замены значений из второго объекта, затем добавьте дополнительные значения из второго объекта.

const obj1 = {
    a: 1,
    b: '',
    c: [],
    d: null
}

const obj2 = {
    a: 2,
    b: null,
    d: 1
}

function mergeObjs(obj1, obj2){
  const merged = {}
  keys1 = Object.keys(obj1);
  keys1.forEach(k1 => {
     merged[k1] = obj2[k1] || obj1[k1]; // replace values from 2nd object, if any
  })
  Object.keys(obj2).forEach(k2 => {
     if (!keys1.includes(k2)) merged[k2] = obj[k2]; // add additional properties from second object, if any
  })
  return merged
}


console.log(mergeObjs(obj1, obj2))
1 голос
/ 17 мая 2019

Использование Lodash от create() и omitBy()

const obj1 = {"a":1,"b":"","c":[],"d":null}

const obj2 = {"a":2,"b":null,"d":1}

const objMerged = _.create(
  _.omitBy(obj1, _.isNull),
  _.omitBy(obj2, _.isNull)
)

console.log(objMerged)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
1 голос
/ 17 мая 2019

Вы можете использовать _.mergeWith(), а в обратном вызове слияния принимать только 2-е значение, если оно не null:

const obj1 = { a: 1, b: '', c: [], d: null }
const obj2 = { a: 2, b: null, d: 1 }

const result = _.mergeWith({}, obj1, obj2, (o, s) => _.isNull(s) ? o : s)

console.log(result)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
1 голос
/ 17 мая 2019

Вы сделали это хорошо, используя Object.assign, просто удалите то, что вам не нужно, прямо перед

Object.keys(obj1).forEach( k => {
    if ( obj1[k] //write the condition you want
        delete obj1[k]
});
1 голос
/ 17 мая 2019

Если вас интересует только первый уровень двух объектов, вы можете сделать что-то вроде этого:

const obj1 = {
  a: 1,
  b: '',
  c: [],
  d: null
}

const obj2 = {
  a: 2,
  b: null,
  d: 1
}

const merged = Object.keys(obj1).concat(Object.keys(obj2)) // create an array that contains the keys of the two objects.
  .filter((k, i, arr) => arr.indexOf(k) === i) // remove duplicate keys
  .reduce((a, c) => {
    a[c] = obj1[c] !== null ? obj1[c] : obj2[c];
    return a;
  }, {});

console.log(merged);

В этом примере проверяется только значение null, вам, вероятно, следует расширить его, чтобы проверить другие, такие как undefined, пустые строки и т. Д.

...