Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将两个嵌套对象组合在一起,同时保留这两个对象的特性,同时将重复的关键帧和值添加在一起_Javascript - Fatal编程技术网

Javascript 将两个嵌套对象组合在一起,同时保留这两个对象的特性,同时将重复的关键帧和值添加在一起

Javascript 将两个嵌套对象组合在一起,同时保留这两个对象的特性,同时将重复的关键帧和值添加在一起,javascript,Javascript,我看过几篇关于将两个对象合并在一起的文章,但大多数都是用于合并包含不包含嵌套元素的对象的对象。当我实现其中一个建议的解决方案时,一个对象的属性被覆盖 const Gnome = () => { return { ExpRate: .20, Abilities: { PickDoors: 1, }, Buffs: { NightSight: 65, MagicRes: 5, }, ... Additi

我看过几篇关于将两个对象合并在一起的文章,但大多数都是用于合并包含不包含嵌套元素的对象的对象。当我实现其中一个建议的解决方案时,一个对象的属性被覆盖

const Gnome = () => {
  return {
    ExpRate: .20,
    Abilities: {
      PickDoors: 1,
    },
    Buffs: {
      NightSight: 65, 
      MagicRes: 5, 
    },
    ... Additional data and behaviors
  };
}

const Thief = () {
  return {
    ExpRate: 2.10, 
    Abilities: {
      Thievery: 1,
      PickDoors: 1, 
    },
    Buffs: {}, 
    // ... Additional data and behavors
  };
}
我一直在尝试将这两个对象合并为:

{
 ExpRate: 2.30,
 Abilities: {
    PickDoors: 2,
    Thievery: 1
 }, 
 Buffs: {
    NightSight: 65,
    MagicRes: 5, 
 }, 
// ... Additional data and behavors from both objects
};
但是,使用Object.assign将覆盖现有键中的值,从而丢失数据。即:

const myGnome = Gnome();
const myThief = Thief();
const myPlayer = Object.assign({}, myGnome, myThief);
我尝试了一些人们推荐的合并方法,但它们似乎都具有与Object.assign()相同的行为; 如有任何建议,将不胜感激。如果这确实是一篇重复的文章,我很喜欢它的链接


提前感谢。

您可以使用递归来实现。下面是一个例子

constgnome=()=>{
返回({
表达式:.20,
能力:{
扒门:1,
},
浅黄色:{
夜视:65,
麦基克雷斯:5,
}
});
}
警察小偷=()=>{
返回({
出口率:2.10,
能力:{
盗窃:1,,
扒门:1,
},
buff:{}
});
}
让小偷=小偷();
让gnone=Gnome();
函数合并(obj1、obj2){
设keys1=对象。键(obj1);
设keys2=Object.keys(obj2);
让objToReturn=Object.assign({},obj1,obj2);
让sameKeys=[…新集合(keys1.filter(key=>keys2.includes(key)).concat(keys2.filter(key=>keys1.includes(key)))]
sameKeys.forEach(key=>{
如果(obj1[key]=“object”的类型)objToReturn[key]=合并(obj1[key],obj2[key]);
否则OBJTORETRUN[钥匙]=obj2[钥匙]+obj1[钥匙];
})
返回objToReturn;
}

日志(合并(小偷,gnone))您可以迭代条目并检查是否找到对象,然后再次调用嵌套对象的函数。如果找到数字,则添加此值

函数合并(a、b){
函数mergeTo(源、目标){
Object.entries(source.forEach([k,v])=>{
if(数组isArray(v)){
目标[k]=目标[k]| |[];
目标[k]。推送(…v);
返回;
}
if(v&&typeof v=='object'){
mergeTo(v,target[k]=target[k]|{});
返回;
}
if(typeof v=='number'){
目标[k]=(目标[k]| 0)+v;
返回;
}
如果(!(目标中的k)){
目标[k]=v;
返回;
}
目标[k]=Array.isArray(目标[k])
?[…目标[k],v]
:[目标[k],v];
});
}
var对象={};
合并到(a,对象);
合并到(b,对象);
返回对象;
}
console.log(合并(
{ExpRate:.20,异能:{PickDoors:1},增益:{NightSight:65,MagicRes:5},数组:[1,2],v:'a'},
{ExpRate:2.10,异能:{thiever:1,PickDoors:1},增益:{},数组:[3,4],v'b',f:true}
));

.as控制台包装{最大高度:100%!重要;顶部:0;}
感谢您的回复。我会试试你的建议。我能够按照建议编写一个函数:

    function isObject(item) {
      return (item && typeof item === 'object' && !Array.isArray(item));
    }

    function mergeDeep(target, source) {
      let output = Object.assign({}, target);
      if (isObject(target) && isObject(source)) {
        Object.keys(source).forEach(key => {
          if (isObject(source[key])) {
            if (!(key in target))
              Object.assign(output, { [key]: source[key] });
            else
              output[key] = mergeDeep(target[key], source[key]);
          } else {
              if(typeof target[key] === 'number' && typeof source[key] === 'number'){
                  source[key] += target[key];
              }

            Object.assign(output, { [key]: source[key] });
          }
        });
      }
      return output;
    }
    console.log(
      mergeDeep(
        {ExpRate: .20, Abilities: {PickDoors: 1}, Buffs: {NightSight: 65, MagicRes: 5}}, 
        {ExpRate: 2.10, Abilities: {Thievery: 1, PickDoors: 1}}
    ));

我将尝试其他建议,因为我担心上述方法可能会变得有点复杂,并在将来导致问题。

我认为您应该自己编写一个递归函数来处理此任务。@Timothy McCune如果
ExpRate
字符串,会发生什么?如果值为
string
Boolean
实际上什么都没有,将被过滤掉。也许应该在数组中收集该值。但我认为op应该回答这个问题。这种方法非常有效!甚至在添加每个对象的行为时(即:向两个对象添加pickDoors()方法)。这个想法是要有几个种族有特定的能力和增益和专业能力。某些种族/职业组合可能具有相同的技能。如果种族/职业组合包含相同的技能定义,则将它们添加到数组中,以避免对象中的重复函数。谢谢。谢谢你的来信。在我为每个对象介绍一些行为之前,这非常有效。IE:向小偷添加一个偷偷的方法很好,但是如果我向两个对象都添加一个PickDoor方法,那么合并将不会产生期望的结果。