Javascript循环遍历对象,甚至在子对象中插入缺少的键
我需要同步两个javascript对象,我想用object1中缺少的键填充object2,而不替换现有键,即使是嵌套键:Javascript循环遍历对象,甚至在子对象中插入缺少的键,javascript,object,nested,Javascript,Object,Nested,我需要同步两个javascript对象,我想用object1中缺少的键填充object2,而不替换现有键,即使是嵌套键: var object1 = { firstName: "Marco", lastName: "Rossi", favoriteFood: {firstCourse: "pasta", secondCourse: "salsiccia"}, favoriteDrink: "Vino", favoriteSong: "O sole mio"
var object1 = {
firstName: "Marco",
lastName: "Rossi",
favoriteFood: {firstCourse: "pasta", secondCourse: "salsiccia"},
favoriteDrink: "Vino",
favoriteSong: "O sole mio"
}
var object2 = {
firstName: "Marco",
lastName: "Rossi",
favoriteFood: {firstCourse: "pasta"},
favoriteSong: "Viaggiare"
}
我真的不知道如何进入嵌套键。特别是要不断检查内部巢穴,如果你有5个巢穴或类似的东西,我知道如何处理第一层,但不进一步向下
objec2的预期结果是
var object2 = {
firstName: "Marco",
lastName: "Rossi",
favoriteFood: {firstCourse: "pasta", secondCourse: "salsiccia"},
favoriteDrink: "Vino",
favoriteSong: "Viaggiare"
}
提前感谢您的帮助。一种方法是检查
typeof()
每个对象属性并递归遍历。您需要遍历整个对象,并询问键/值对的变量类型。如果它是一个物体,再做一次
for(var prop in object1){
if(object1.hasOwnProperty(prop)){
if(!(prop in object2)){
object2[prop] = object1[prop];
}
}
}
这个例子很小
(我将不讨论这个问题,但Crossfires版本已经更快、更完整了)您需要编写递归函数来处理嵌套对象。也许是这样的:
var object1={
名字:“马可”,
姓:“罗西”,
最喜欢的食物:{第一道菜:“意大利面”,第二道菜:“盐腌菜”},
favoriteMovie:{评级:7,标题:“星期一”},
最爱的饮料:“葡萄酒”,
最喜欢的歌曲:“哦,我的唯一”
}
var object2={
名字:“马可”,
姓:“罗西”,
最喜欢的食物:{第一道菜:“意大利面”},
最喜欢的歌曲:“维亚吉尔”
}
函数fillObject(从、到){
for(从中输入变量){
if(来自.hasOwnProperty(键)){
if(Object.prototype.toString.call(从[key])=='[Object Object]'){
如果(!to.hasOwnProperty(键)){
到[键]={};
}
fillObject(从[key],到[key]);
}
如果(!to.hasOwnProperty(键)){
到[键]=从[键];
}
}
}
}
fillObject(object1、object2);
警报(JSON.stringify(object2,null,)代码>这对我很有效。我认为这很简单。只需检查object2中是否存在该属性,如果它不是对象,请保留它或复制它。如果它是一个递归对象
(function(){
console.log("EXECTURING");
var object1 = {
firstName: "Marco",
lastName: "Rossi",
favoriteFood: {firstCourse: "pasta", secondCourse: "salsiccia"},
favoriteDrink: "Vino",
favoriteSong: "O sole mio"
};
var object2 = {
firstName: "Marco",
lastName: "Rossi",
favoriteFood: {firstCourse: "pasta"},
favoriteSong: "Viaggiare"
};
for( key in object1) {
if(object1.hasOwnProperty(key)) {
copyToB(key, object1, object2);
}
}
})();
function copyToB(key, o1, o2) {
if(typeof(o1[key]) !== "object") {
if(typeof o2[key] === "undefined")
o2[key] = o1[key];
return;
}
var tempObj = o2[key];
for(k in o1[key]) {
copyToB(k, o1[key], tempObj);
}
o2[key] = tempObj;
}
如果目标中的路径为null,所有这些答案都将失败,因此在递归之前,有必要深入查看对象1级,检查目标节点是否为null,如果是,则在递归之前更新它
注意:我的回答与其他人的观点顺序不同。a是要检查是否缺少关键帧的项,b是具有正确关键帧的引用对象。我的函数还返回true/false,以确定是否对a进行了任何更改。当缺少键时,它还会将默认值从b复制到a。
function has (o,k) {
return typeof o==='object'&&(o.hasOwnProperty(k)||o[k]!==undefined);
}
function recursiveCheck( a, b ) {
var c = false;//whether we have changes. the calling scope wants to know
// a is the object to check, b is the target
for(let k in b) {
if(!has(a,k)) {
c=true;
a[k] = b[k];
}else{
// if b[k] is an object, we recursively check on the children for changes
// we only want to manipulate a[k] if b[k]=== object and not null!!!
if(typeof b[k]==='object'&&b[k]!==null){
for(let k2 in b[k]) {
if(a[k]===null){
a[k]=b[k];
c=true;
}
if( (!has(a[k],k2) || a[k][k2]===null) && typeof b[k][k2]==='object' && b[k][k2]!==null){
a[k][k2] = b[k][k2];
c=true;
}
}
const hasChange = recursiveCheck(a[k],b[k]);
c = c || hasChange;
}
}
}
return c;
}
用法
var a = { foo: null, bar: true };//this is the object we are checking
var b = { foo:{test:1,hello:false},bar: false}; //this is the object with correct keys and default values that should copy over to a when needed.
const didChange = recursiveCheck(a,b);
证明输出正确的测试用例
var target = {
private:{
has:false,
cost:0
},
shared:{
has:false,
cost:0
}
}
var inputs = [
{},// true
{private:null,shared:null},// true
{private:{has:true},shared:{cost:50}},// true
{private:{has:true,cost:500},shared:{has:false,cost:250}}// false
];
console.log('inputs---',inputs);
const results = inputs.map(item=>recursiveCheck(item,target));
console.log('inputs(transformed)---',inputs);
console.log('results---',results); // should be [true, true, true, false]
另一个问题的答案可能重复提到jQuery和非jQuery的方法,那么嵌套对象呢?我认为这对嵌套对象不起作用。如果两者都有相同的对象作为键,并且object2中缺少一些键,那么这段代码将不允许复制,因为:如果(!(object2中的prop))在彻底测试了这一点之后,有一种情况不起作用。如果嵌套键不存在,则不会创建它。假设object2中不存在favoriteFood,此代码不会在object1中创建一个。我还在努力理解为什么。当然!如果发现其他问题,请随时返回。如果预期对象为null
,则此操作将失败。例如,如果favoriteFood
为null,则它将保持null
。如果有人知道修复方法,我将不胜感激。
var a = { foo: null, bar: true };//this is the object we are checking
var b = { foo:{test:1,hello:false},bar: false}; //this is the object with correct keys and default values that should copy over to a when needed.
const didChange = recursiveCheck(a,b);
var target = {
private:{
has:false,
cost:0
},
shared:{
has:false,
cost:0
}
}
var inputs = [
{},// true
{private:null,shared:null},// true
{private:{has:true},shared:{cost:50}},// true
{private:{has:true,cost:500},shared:{has:false,cost:250}}// false
];
console.log('inputs---',inputs);
const results = inputs.map(item=>recursiveCheck(item,target));
console.log('inputs(transformed)---',inputs);
console.log('results---',results); // should be [true, true, true, false]