объединить 2 объекта в значениях javascript и concat без переопределения свойств - PullRequest
0 голосов
/ 27 января 2019

Я просмотрел кучу постов по этому поводу, но, похоже, ни одно из них не соответствует тому, что я пытаюсь сделать, или, по крайней мере, ни одно из них, которые я нашел во время поиска.

У меня есть два объекта, и мне нужно объединить их оба без переопределения каких-либо свойств.Если два ключа совпадают, то мне нужно согласовать их значения.Пример:

const base = {
  icon: "icon--value1"
  item: "item--value"
} 

const extend = {
  icon: "icon--value2"
  item: "item--value"
  list: "list--value"
} 

Комбинированные объекты

const combined = { 
  icon: "icon--value1 icon--value2"
  item: "item--value"
  list: "list--value"
}

Я пытался использовать es6 assign и es6 destruuring, но они просто переопределяют значения.

 combined = {...base, ... extend}

Не был результат, который я был после.Кто-нибудь знает, как я мог достичь вышеизложенного?Заранее благодарю за любую помощь.

Ответы [ 3 ]

0 голосов
/ 27 января 2019

Если вы счастливы использовать lodash (что также означает не изобретать велосипед), вы можете использовать функцию mergeWith(), задокументированную здесь . Например:

const base = {
  icon: "icon--value1",
  item: "item--value"
} 

const extend = {
  icon: "icon--value2",
  item: "item--value",
  list: "list--value"
} 

const res = _.mergeWith(base, extend, (objVal, srcVal) => 
  objVal && objVal !== srcVal ? `${objVal} ${srcVal}` : srcVal
)

console.log(res)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>

В качестве альтернативы вы можете создать свой собственный mergeWith, выполнив следующие действия:

const base = {
  icon: "icon--value1",
  item: "item--value"
} 

const extend = {
  icon: "icon--value2",
  item: "item--value",
  list: "list--value"
} 

const customMergeWith = (a, b, proc) => {
  const result = { ...a }
  Object.keys(b).forEach(k => {
    result[k] = proc(result[k], b[k])
  })
  return result
}

const res = customMergeWith(base, extend, (objVal, srcVal) => 
  objVal && objVal !== srcVal ? `${objVal} ${srcVal}` : srcVal
)

console.log(res)

Просто отметьте, что я лично предпочел бы использовать версию lodash, так как она будет более надежной и требует меньше кода, о котором вам нужно беспокоиться. Не пытайтесь изобретать велосипед, если вам не нужно.


Наконец, люди, кажется, считают, что таких людей, как Лодаш, следует избегать, вероятно, из-за их размера. Однако вы можете импортировать только то, что вам нужно в эти дни. Подробности см. В этом ответе: Как импортировать одну функцию Lodash?

0 голосов
/ 27 января 2019

Для меня это был бы самый читаемый способ справиться с этим ...

const base = {icon: "icon--value1",item: "item--value"} 
const extend = {icon: "icon--value2",item: "item--value", list: "list--value"} 

let keys = [...Object.keys(base), ...Object.keys(extend)]

let output = keys.reduce((acc, key) => {
   if (acc[key]) return acc;
   let newVal = (
       (base[key] || "") 
      + " " 
      +(extend[key] || "")
   );
   return {...acc, [key]: newVal.trim().trimStart() };            
},{})
0 голосов
/ 27 января 2019

Вы можете сделать это, используя reduce.

Вот идея: -

  1. Мы делаем Set из ключей от обоих объектов.
  2. А потом мы перебираем массив ключей.И для каждого ключа мы ищем значение в обоих объектах и ​​согласовываем их (Имейте в виду, что нам нужно использовать || здесь, иначе, если один объект не имеет свойства, вернется undefined, который будет добавлен в вывод, который не являетсяпо желанию).И затем мы добавляем ключ и значение к выходному объекту.

const base = {icon: "icon--value1",item: "item--value"} 
const extend = {icon: "icon--value2",item: "item--value", list: "list--value"} 

let keys = [...new Set([...Object.keys(base), ...Object.keys(extend)]) ]

let output = keys.reduce( (op, cur) => {
  if((base[cur] && extend[cur]) && (base[cur] !== extend[cur])){
    op[cur] = (base[cur]||'') + " " + (extend[cur]||'')
  }
  else {
    op[cur] = base[cur] || extend[cur]
  }
  return op;
},{})

console.log(output)

Альтернатива для достижения того, что я делал с Set

const base = {icon: "icon--value1",item: "item--value"} 
    const extend = {icon: "icon--value2",item: "item--value", list: "list--value"} 

let keys = [...Object.keys(base), ...Object.keys(extend)]

let uniqueKeys = Object.keys(keys.reduce((output,cur)=>{
  if( !output[cur] ){
    output[cur]=''
  }
  return output;
},{}))

let output = uniqueKeys.reduce( (op, cur) => {
  if((base[cur] && extend[cur]) && (base[cur] !== extend[cur])){
    op[cur] = (base[cur]||'') + " " + (extend[cur]||'')
  }
  else {
    op[cur] = base[cur] || extend[cur]
  }
  return op;
},{})

console.log(output)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...