【问题标题】:Does PHP or PHPUnit or Laravel have a function for recursive array comparison?PHP 或 PHPUnit 或 Laravel 是否具有递归数组比较的功能?
【发布时间】:2019-11-22 08:11:43
【问题描述】:

我的一些 PHPUnit 测试将 Facebook 称为“php-business-sdk”,因此我可以确信 Facebook 的 API 会继续按我的预期运行。例如。 getInsights()FacebookAds\Object\Ad 内。

而那些 PHPUnit 测试一直在使用 assertEqualsCanonicalizing

但是,测试仍然很脆弱; Facebook 的 API 经常改变 不仅结果中 顶级 数组(关联数组的数组)的顺序,而且还改变内部键的顺序关联数组。

所以我真正需要的是assertEqualsCanonicalizing 的一个版本,它是递归的,并且对顶级数组中关联数组的键的排序也是不可知的。

如果这样的函数已经存在(可能在 PHP、PHPUnit、Laravel 或其他地方),我宁愿不编写自己的代码。是吗?

附:下面是一个简化的结果示例:

[
  {
    "Spend": "$3,009",
    "Campaign ID": 3335626793661,
    "Reach": 37640,
    "Unique Inline Link Clicks": 2368
  },
  {
    "Spend": "$1,030",
    "Campaign ID": 3335626793662,
    "Reach": 1620,
    "Unique Inline Link Clicks": 231
  }
]

(想象下一次 API 返回相同的数据,但“Reach”在“Spend”之前写入,对象的顺序也可以改变。)

附注这不是链接问题的重复,因为我专门询问如何不知道 inner 数组键的排序顺序。

【问题讨论】:

标签: php laravel phpunit facebook-php-sdk


【解决方案1】:

in_array 没有递归工作的本地方法。

但是很多人已经通过这样的助手解决了这个问题:

    private function in_array_recursive($needle, $haystack, $strict = true)
    {
        foreach ($haystack as $value) {
            if (($strict ? $value === $needle : $value == $needle) || (is_array($value) && $this->in_array_recursive($needle, $value, $strict))) {
                return true;
            }
        }
        return false;
    }

【讨论】:

    【解决方案2】:

    直到有人展示现有的本机功能或比这更好的东西,这似乎对我的目的有用:

    /**
     * @see https://stackoverflow.com/q/57008999/470749
     *
     * @param array $expected
     * @param array $actual
     */
    public function assertEqualsCanonicalizingInner($expected, $actual) {
        try {
            $this->assertEqualsCanonicalizing(AT::sortInnerArrays($expected), AT::sortInnerArrays($actual));
        } catch (\Exception $e) {
            $expectedSortedJson = json_encode(AT::sortInnerArrays($expected));
            $actualSortedJson = json_encode(AT::sortInnerArrays($actual));
            $this->assertTrue(false, __FUNCTION__ . ' failed: ' . PHP_EOL . $expectedSortedJson . PHP_EOL . ' vs ' . PHP_EOL . $actualSortedJson);
        }
    }
    
    /**
     * @see https://stackoverflow.com/q/57008999/470749
     * 
     * @param array $arr
     * @return array
     */
    public static function sortInnerArrays($arr) {
        $resultingOuterArr = [];
        foreach ($arr as $k => $v) {
            if (is_array($v)) {
                foreach ($v as $kInner => $vInner) {
                    if (is_array($vInner)) {
                        $v[$kInner] = self::sortInnerArrays($vInner);
                    }
                }
                ksort($v);
            }
            $resultingOuterArr[$k] = $v;
        }
        sort($resultingOuterArr);
        return $resultingOuterArr;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 2012-09-03
      • 1970-01-01
      • 2018-08-28
      • 2011-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多