【问题标题】:In AS3, how to check if two JSON objects are equal?在 AS3 中,如何检查两个 JSON 对象是否相等?
【发布时间】:2013-04-04 15:56:11
【问题描述】:

标题几乎说明了这一点。我有两个 JSON 对象,我想知道它们是否相等(具有所有相同的属性值)。

我可以将它们都字符串化,但我不确定两个相等的对象是否总是会产生相同的输出:

例如:

{
    "firstName": "John",
    "lastName": "Smith",
    "age": 25,
    "favoriteColors": ["blue", "green", "red"]
}

是不同的字符串:

{
    "age": 25,
    "lastName": "Smith",
    "firstName": "John",
    "favoriteColors": ["blue", "green", "red"]
}

但作为对象,它们具有相同的属性。

【问题讨论】:

  • 您不能一次检查每个属性吗? if age = age, if firstName = firstName, etc.
  • 我正在寻找适用于任何 JSON 对象的通用解决方案。另外, favoriteColors 是一个数组,所以简单的相等比较是行不通的。
  • 我对我的 JSON 有点生疏了,但是你能不能遍历第一个对象的属性,然后为每个对象检查第二个对象的属性,直到找到匹配的属性。一旦您拥有两个匹配的属性,请检查它们的值是否相同。继续循环,直到检查完所有属性。这也适用于数组,只需检查它是否为数组,然后为数组项进入另一个循环。

标签: json actionscript-3


【解决方案1】:

Flex SDK 中有一个方法。它在ObjectUtil 类中。以下是来源的描述:

/**
     * Compares the Objects and returns an integer value 
     * indicating if the first item is less than greater than or equal to
     * the second item.
     * This method will recursively compare properties on nested objects and
     * will return as soon as a non-zero result is found.
     * By default this method will recurse to the deepest level of any property.
     * To change the depth for comparison specify a non-negative value for
     * the depth parameter.
     * @param   a   Object.
     * @param   b   Object.
     * @param   depth   Indicates how many levels should be 
     *   recursed when performing the comparison.
     *   Set this value to 0 for a shallow comparison of only the primitive 
     *   representation of each property.
     *   For example:
     *   var a:Object = {name:"Bob", info:[1,2,3]};
     *   var b:Object = {name:"Alice", info:[5,6,7]};
     *   var c:int = ObjectUtil.compare(a, b, 0);In the above example the complex properties of a and 
     *   b will be flattened by a call to toString()
     *   when doing the comparison.
     *   In this case the info property will be turned into a string
     *   when performing the comparison.
     * @return  Return 0 if a and b are null, NaN, or equal. 
     *   Return 1 if a is null or greater than b. 
     *   Return -1 if b is null or greater than a.
     * @langversion 3.0
     * @playerversion   Flash 9
     * @playerversion   AIR 1.1
     * @productversion  Flex 3
     */
    public static function compare (a:Object, b:Object, depth:int=-1) : int;

如果您不想要整个 SDK,也许您可​​以获取此函数/类并使用该源代码。

你可以看到源here。大部分工作都在函数internalCompare中完成。

【讨论】:

  • 奇怪的是,Adobe 的在线文档中似乎没有出现这种方法。我也对其预期目的感到有些困惑——它似乎是为排序而设计的,但对于具有多个属性的对象,排序顺序很难预测。
  • 该函数用于比较2个对象,可以通过将它作为比较函数传递给sort来进行排序。不知道为什么它没有显示在 Adob​​e 的文档中可能是因为它是 Flex 的一部分。但是您可以只使用该类,而无需使用整个 SDK 或制作 Flex App。
  • @justkevin adobe 文档页面上的过滤器可能未设置为显示 sdk 文档
【解决方案2】:

编辑:Barış 的答案是最好的选择,因为它已经过试验和测试。以防万一这对某人有用:

鉴于 JSON 值仅限于一小组简单类型,因此应该可以相当轻松地通过属性进行递归。这些方面的内容适用于您的示例:

private function areEqual(a:Object, b:Object):Boolean {
    if (a === null || a is Number || a is Boolean || a is String) {
        // Compare primitive values.
        return a === b;
    } else {
        var p:*;
        for (p in a) {
            // Check if a and b have different values for p.
            if (!areEqual(a[p], b[p])) {
                return false;
            }
        }
        for (p in b) {
            // Check if b has a value which a does not.
            if (!a[p]) {
                return false;
            }
        }
        return true;
    }
    return false;
}

【讨论】:

    【解决方案3】:

    也许您可以将两个对象转换为字符串然后比较它们

    function compareJSON(a:Object, b:Object):Boolean
    {
      return JSON.stringify(a)===JSON.stringify(b);
    }
    

    【讨论】:

    • 这不起作用,因为字符串化时属性没有得到排序。
    猜你喜欢
    • 2016-10-22
    • 2023-03-07
    • 2016-06-27
    • 1970-01-01
    • 2012-06-10
    • 2019-11-04
    • 1970-01-01
    • 2017-02-20
    相关资源
    最近更新 更多