假设我创建了一个名为Store的类。 这个类有几个元素,如Name,PhoneNumber,Owner。
我已经创建了这个类的2个实例,并想知道哪些值不同。
因此,假设Store1和Store2是此类的实例。
Store1.Name = "John's Corner";
Store1.PhoneNumber = 111222333;
Store1.Owner = "John";
Store2.Name = "John's Corner";
Store2.PhoneNumber = 444555666;
Store2.Owner = "John";
通常比较一下:
if (Store1.Name == Store2.Name) output.text += "Store name is different."
if (Store1.PhoneNumber == Store2.PhoneNumber) output.text += "Store Phone Number is different."
if (Store1.Owner == Store2.Owner) output.text += "Store Owner is different."
有没有办法自动遍历类实例的所有元素,并将它们与另一个类实例中的相同元素进行比较,并在它们不同时返回一些内容?
这可能很明显,但我无法弄清楚。
答案 0 :(得分:2)
对于密封属性,您可以描述类型然后循环它的加速器:
var typeXML:XML = describeType(Store1);
var diffs:Dictionary = new Dictionary();
for each(var prop:XML in type..accessor){
if(Store1[prop] != Store2[prop]){
diffs[prop] = new Array(Store1[prop],Store2[prop]);
}
}
抱歉,我面前没有编译器,所以我无法检查这些。看看typeXML对象,看看你需要在for循环中循环。
答案 1 :(得分:0)
试
for (var property in Store1)
{
if (Store1[property] == Store2[property])
{
trace("property-" + property + ", value-" + Store1[property]);
}
}
显然,如果商店1和商店2的类型不同,这将无效。
答案 2 :(得分:0)
按照詹姆斯的代码,您可以将第一行更改为:
for (var property in ["property1","property2","property3")
如果您需要动态执行此操作,可以使用describeType检索该类的所有公共属性。
答案 3 :(得分:0)
除非你想要一个完全通用的解决方案(你还要比较多少个类?),在相应的类中编写一个自定义compare
函数,该函数通过类的属性并返回一个布尔值。
更新:
谢谢你describeType
。关于describeType要注意的一件事是它只反映了类的公共变量/属性。 privateType / protected / internal stuff不包含在describeType的输出中。因此,如果您使用它来比较具有相同公共属性但具有不同私有属性的两个对象,它仍然会告诉您它们是相等的。
这是一个AS类及其describeType输出。 的 Data.as 强>
package
{
public class Data
{
private var privateVar:Boolean;
protected var protectedVar:Boolean;
internal var internalVar:Boolean;
var noModifierVar:Boolean;
public var publicVar:Boolean;
public function set writeOnlyProp(value:Boolean):void
{
}
public function get readOnlyProp():Boolean
{
return true;
}
public function set readWriteProp(value:Boolean):void
{
}
public function get readWriteProp():Boolean
{
return false;
}
public function Data(pub:Boolean = false, priv:Boolean = false,
prot:Boolean = false, inter:Boolean = false)
{
this.privateVar = priv;
this.protectedVar = prot;
this.internalVar = inter;
this.publicVar = pub;
}
}
}
describeType
的输出:请注意此处仅列出了公共变量。
<type name="Data" base="Object" isDynamic="false" isFinal="false" isStatic="false">
<extendsClass type="Object"/>
<constructor>
<parameter index="1" type="Boolean" optional="true"/>
<parameter index="2" type="Boolean" optional="true"/>
<parameter index="3" type="Boolean" optional="true"/>
<parameter index="4" type="Boolean" optional="true"/>
</constructor>
<accessor name="readOnlyProp" access="readonly" type="Boolean" declaredBy="Data"/>
<variable name="publicVar" type="Boolean"/>
<accessor name="readWriteProp" access="readwrite" type="Boolean" declaredBy="Data"/>
<accessor name="writeOnlyProp" access="writeonly" type="Boolean" declaredBy="Data"/>
</type>
通用比较代码如下所示:
public static function compareObjects(a:Object, b:Object):Boolean
{
var description:XML = describeType(a);
var bDescription:XML = describeType(b);
//different classes
if(description.toXMLString() != bDescription.toXMLString())
return false;
if(String(description.@isDynamic) == "true")
{
var t:*;
for(t in a)
if(a[t] != b[t])
return false;
//Just in case b has a dynamic property that a doesn't
for(t in b)
if(a[t] != b[t])
return false;
}
var properties:Array = [];
//readonly and readwrite properties
var accessors:XMLList = description.accessor.(@access != "writeonly");
var type:XML;
for each(type in accessors)
properties.push(String(type.@name));
//other variables
var variables:XMLList = description.variable;
for each(type in variables)
properties.push(String(type.@name));
for each(var prop:String in properties)
{
if(a[prop] != b[prop])
return false;
}
return true;
}
PS:写完所有这些代码后,我仍然觉得在相应的类中编写自定义代码是正确的方法,因为这不会考虑私有/受保护的数据。
答案 4 :(得分:0)
只需将两个对象序列化为JSON字符串并进行字符串比较。