合并我的对象并获得预期的结果

时间:2016-01-27 23:12:20

标签: javascript jquery html arrays

我正在尝试合并我的对象并得到如下所示的结果

{
    "sports": {
        "basketball": "kobe",
        "swimming": {
        },
        "football": "ronaldo",
        "running": "",
        "highJump": ""
    },
    "calendar": ["21", "25", "30"]
}
  • 在某些地方,我在逻辑上做错了你可以帮帮我吗
  • 但如果我改变了sportA和sportsB值,我会得到预期 结果......不确定我当前场景中的问题
  • 在下面提供我的代码。
  • 拨弄

https://jsfiddle.net/tjLk0frq/3/

var sportsA ={
    "sports": {
        "basketball": "kobe",
        "football": "ronaldo"
    }
};

var sportsB ={
    "sports": {
        "basketball": "",
        "swimming": {
        },
        "football": "",
        "running": "",
        "highJump": ""
    },
    "calendar": ["21", "25", "30"]
};

function merge(sportsA, sportsB) {
    for( var p in sportsB )
        if( sportsA.hasOwnProperty(p) )
            sportsA[p] = typeof sportsB[p] === 'object' ? merge(sportsA[p], sportsB[p]) : sportsB[p];

    return sportsA;
}

merge(sportsA, sportsB );
console.log("unexpected result" + sportsA ); 
console.log( sportsA ); 


//expected
/*
{
    "sports": {
        "basketball": "kobe",
        "swimming": {
        },
        "football": "ronaldo",
        "running": "",
        "highJump": ""
    },
    "calendar": ["21", "25", "30"]
}
*/

4 个答案:

答案 0 :(得分:1)

您可以使用启用了深度合并的jQuery' extend method来执行此操作:

var output = $.extend(true, sportsB, sportsA)

输出:

{
    "sports": {
        "basketball": "kobe",
        "swimming": {},
        "football": "ronaldo",
        "running": "",
        "highJump": ""
    },
    "calendar": ["21", "25", "30"]
}

答案 1 :(得分:0)

你去(纯JS):

function merge(obj1, obj2) {
    var result = {};

    for (var prop in obj1) {
        if (typeof obj1[prop] === "object" && typeof obj2[prop] === "object")
            result[prop] = merge(obj1[prop], obj2[prop]);
        else
            result[prop] = obj1[prop];
    }

    for (var prop in obj2) {
        result[prop] = (result[prop]? result[prop]: obj2[prop]);
    }

    return result;
}

console.log(merge(sportsA, sportsB));

返回一个新对象,而不是修改现有对象。

在第一个for..in循环中,我们检查是否需要先递归,否则设置result的属性。

在第二个for..in循环中,我们检查属性是否已定义或是否为空,并相应地设置属性。

输出:

{
    "sports": {
        "basketball": "kobe",
        "football": "ronaldo",
        "swimming": {},
        "running": "",
        "highJump": ""
    },
    "calendar": ["21", "25", "30"]
}

JSFiddle demo

答案 2 :(得分:0)

在您检查sportsA.hasOwnProperty(p)时,如果您只更新sportsA中的属性,但未添加sportsB中的新内容,则会出错。

如果sportsB[p]有假值,您也不想更新它,因为我已使用(sportsB[p] || sportsA[p])

检查此代码。



var sportsA ={
	"sports": {
	    "basketball": "kobe",
	    "football": "ronaldo"
	}
};

var sportsB ={
	"sports": {
	    "basketball": "",
	    "swimming": {
	    },
	    "football": "",
	    "running": "",
	    "highJump": ""
	},
	"calendar": ["21", "25", "30"]
};

function merge(sportsA, sportsB) {

    for( var p in sportsB )
        if( sportsA.hasOwnProperty(p) ) {
          sportsA[p] = typeof sportsB[p] === 'object' ? merge(sportsA[p], sportsB[p]) : (sportsB[p] || sportsA[p]);
        } else {
          sportsA[p] = sportsB[p];
        }
        

    return sportsA;
}

merge(sportsA, sportsB );
console.log("unexpected result" + sportsA ); 
console.log( sportsA ); 




答案 3 :(得分:-2)

逻辑正在破坏,因为当你只在其中一个对象中循环属性键时,你不会看到只存在于另一个对象中的属性键。

您可以使用Object.keys()获取对象的根级别键,它返回属性名称的数组。然后,您可以在同一级别合并两组密钥,并了解所需的所有最终输出属性

然后迭代这些以获得最终结果