AS3中的对象合并

3

我想将两个包含一些相同键但不同值的A3对象合并在一起。我找到了很多关于添加两个对象的帖子,但我想将两个对象合并在一起,这样如果第二个对象具有不同的值,则它们将具有优先权。我有以下两个对象:

    _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;   

我不确定是否应该使用Array.concat来完成这个任务,还是有更简单的解决方法?如果有帮助,请告诉我。
5个回答

3
下面是合并方法
    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 Verdana obj1 未定义 -> 新值 = Verdana

字体颜色:obj0 16777215 obj1 16777215 -> 新值 = 16777215

基础颜色:obj0 3158583 obj1 未定义 -> 新值 = 3158583

动画:obj0 false obj1 true -> 新值 = true

基础字体大小:obj0 14 obj1 10 -> 新值 = 10

重要的一行是:

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

它会递归地在新对象“obj”上创建属性,并检查该属性是否被分配在第二个对象上,如果是,则将第二个对象的值分配给该属性,否则它会回退到第一个对象上该属性的值。
注意:如果第一个对象没有设置值,则不会在第二个对象中查找。

这是@bmleite推荐的更简洁的方式 :) - nicoptere

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);

据我所理解,意图是仅合并“不同的值”,而不是新属性。要进行“完全”合并,请将以下行更改为var result:Object = ObjectUtil.copy(obj2);。这不是最优的,但适用于大多数情况。 - bmleite

2
如果您想要覆盖第一个对象中的现有值,只需执行以下操作:
for ( var p in _propsObj2 )
    _propsObj[p] = _propsObj2[p];

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框架如何链接样式设置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接