2011-03-18 71 views
3

我想将两个A3对象合并在一起,其中包含一些相同的Keys但不同的值。我发现很多关于添加两个对象的帖子,但我想将两个对象合并在一起,所以如果第二个对象具有不同的值,他们会优先考虑。下面我有两个对象:合并AS3中的对象

_propsObj = new Object(); 
    _propsObj.baseColour = 0x303237; 
    _propsObj.animation = false; 
    _propsObj.font = "Verdana"; 
    _propsObj.fontColour = 0xffffff; 
    _propsObj.baseFontSize = 14;  

    _propsObj2 = new Object(); 
    _propsObj2.animation = true;   
    _propsObj2.fontColour = 0xffffff; 
    _propsObj2.baseFontSize = 10; 

我想要的输出中的对象将接受第二个对象的新值,但保持第一对象的值:

_outputObj.baseColour = 0x303237; 
    _outputObj.animation = true; 
    _outputObj.font = "Verdana"; 
    _outputObj.fontColour = 0xffffff; 
    _outputObj.baseFontSize = 10; 

我不知道我是否应该正在使用Arrray.concat做到这一点,或者如果有更简单的解决方案?任何帮助,将不胜感激。

回答

4

合并方法下文

var _propsObj:Object = new Object(); 
    _propsObj.baseColour = 0x303237; 
    _propsObj.animation = false; 
    _propsObj.font = "Verdana"; 
    _propsObj.fontColour = 0xffffff; 
    _propsObj.baseFontSize = 14;  

    var _propsObj2:Object = new Object(); 
    _propsObj2.animation = true;   
    _propsObj2.fontColour = 0xffffff; 
    _propsObj2.baseFontSize = 10; 

    var merged:Object = merge(_propsObj, _propsObj2); 

    private function merge(obj0:Object, obj1:Object):Object 
    { 
     var obj:Object = { }; 
     for(var p:String in obj0) 
     { 
      obj[ p ] = (obj1[ p ] != null) ? obj1[ p ] : obj0[ p ]; 
      trace(p, ' : obj0', obj0[ p ], 'obj1', obj1[ p ], '-> new value = ', obj[ p ]); 
     } 
     return obj; 
    } 

痕迹:

字体:obj0宋体OBJ1未定义 - >新值=宋体

fontColour:obj0 16777215 OBJ1 16777215 - >新值= 16777215

baseColour:obj0 3158583 obj1 undefined - > new value = 3158583

动画:obj0假OBJ1真 - >新值=真

baseFontSize:obj0 14 OBJ1 10 - >新值= 10

重要路线是:

obj[ p ] = (obj1[ p ] != null) ? obj1[ p ] : obj0[ p ]; 

它会递归地在新的Object'obj'上创建属性,并检查该属性是否分配给第二个对象,如果是,则将第二个对象的值分配给该属性,否则将回退到该属性的值冷杉t对象。

注意:如果没有在第一个对象上设置一个值,它将不会在第二个对象中查找。

+0

完美!感谢你! – redHouse71 2011-03-18 11:42:34

+0

那是什么也@bmleite sugeested在更紧凑的方式:) – nicoptere 2011-03-18 12:19:31

3

您可以使用这样的事情:

private function merge(obj1:Object, obj2:Object):Object { 
    var result:Object = new Object(); 
    for (var param:String in obj1) { 
     result[param] = (obj2[param] ? obj2[param] : obj1[param]); 
    } 
    return result; 
} 

用法:

_outputObj = merge(_propsObj, _propsObj2); 
+0

嗯,我明白的意图,只会考虑键从第一对象... – Veehmot 2012-10-04 04:58:21

+0

@Veehmot至于是合并只是“不同的值”,而不是新的属性。要做一个“完整”合并,将下面一行'var result:Object = new Object();'改成'var result:Object = ObjectUtil.copy(obj2);'。这不是最佳的,但适用于大多数情况。 – bmleite 2012-10-17 18:02:02

1
var _propsObj:Object = new Object(); 
_propsObj.baseColour = 0x303237; 
_propsObj.animation = false; 
_propsObj.font = "Verdana"; 
_propsObj.fontColour = 0xffffff; 
_propsObj.baseFontSize = 14;  

var _propsObj2:Object = new Object(); 
_propsObj2.animation = true;   
_propsObj2.fontColour = 0xffffff; 
_propsObj2.baseFontSize = 10; 

var mergedObj:Object = new Object(); 

//Adds the values from the first object 
for (var r in _propsObj) 
{ 
    mergedObj[r] = _propsObj[r]; 
} 

//Adds the values from the second object 
for(var s in _propsObj2) 
{ 
    mergedObj[s] = _propsObj2[s]; 
} 

//Checking the merged values 
for(var t in mergedObj) 
{ 
    trace([t, mergedObj[t]]); 
} 
1

那么,这里的,做它一个通用的实用功能:

public static function zip(objects:Array):Object 
{ 
    var r:Object = {}; 

    for each (var o:Object in objects) 
     for (var k:String in o) 
      r[k] = o[k]; 

    return r; 
} 

用法示例:

var obj:Object = { 
    "foo": 1, 
    "bar": 2, 
    "baz": 3 
}; 

var obj2:Object = { 
    "bar": 4, 
    "baz": 6 
}; 

var obj3:Object = { 
    "foo": 3, 
    "bar": 6 
}; 

var result:Object = zip([obj, obj2, obj3]); 

for (var k:String in result) 
    trace("Property:", k, result[k]); 

输出:

Property: foo 3 
Property: baz 6 
Property: bar 6 

边注:这是一个“有损”方法得到的对象不知道是哪里的各个属性的来源,并只保留最新版本的价值。如果你想保留这些信息,那么有另一种方法可以使用原型链来做到这一点。例如,Flex框架如何链接样式设置。

+0

非常感谢! – redHouse71 2011-03-18 15:42:56

2

如果你想覆盖的第一个对象中现有的值,你可能只是这样做:

for (var p in _propsObj2) 
    _propsObj[p] = _propsObj2[p];