为什么array_diff_uassoc比较键,其价值不匹配 [英] Why does array_diff_uassoc compares keys whose value do not match

查看:143
本文介绍了为什么array_diff_uassoc比较键,其价值不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚看了的质疑了解奇怪的PHP行为,即使我可以研究多一点,我远不了解它。

I just read that question about strange php behaviour, and even though I could research a bit more, I'm nowhere near understanding it.

我假设读者读了原来的问题,并意识到OP的code座和样品的,但在短期,OP正试图这两个数组比较,虽然结果还是不错的,比较功能似乎被称为不正常:

I assume the reader has read the original question and is aware of OP's code block and sample, but in short, OP is trying to compare those two arrays, and while the result is good, the compare function seems to be called erratically:

$chomik = new chomik('a');
$a = array(5, $chomik, $chomik, $chomik);
$b = array($chomik, 'b', 'c', 'd');
array_diff_uassoc($a, $b, 'compare');

文档是有点晦涩......但它指出:

The documentation is a bit obscure... but it does state that:

如果第一个参数被认为是<强>分别小于,等于,或大于第二更大的比较函数必须返回小于一个整数,等于或大于零。

The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.

据我了解,这意味着比较()功能应该更是这样的:

As I understand it, that means that the compare() function should be more like this:

function compare($a, $b) {
    echo("$a : $b<br/>");
    if($a === $b) return 0;
    else if ($a > $b) return 1;
    else return -1;
}

然而,这仍然给非常奇怪的结果,甚至更多重复

however this still gives very strange results, with even more "duplicates"


1 : 0
1 : 2
3 : 1
2 : 1
3 : 2
1 : 0
1 : 2
3 : 1
2 : 1
3 : 2
0 : 0
1 : 0
1 : 1
2 : 0
2 : 1
2 : 2
3 : 0
3 : 1
3 : 2
3 : 3

面对种种质疑

,<我一个href=\"https://pear.php.net/reference/PHP_Compat-latest/__filesource/fsource_PHP_Compat__PHP_Compat-1.6.0a3CompatFunctionarray_diff_uassoc.php.html\"相对=nofollow>阅读compat的PHP函数,并在检查实际发生的部分有趣的是:

faced with many doubts, I read the compat php function, and the part where the check actually happens is interesting:

foreach ($args[0] as $k => $v) {
    for ($i = 1; $i < $array_count; $i++) {
        foreach ($args[$i] as $kk => $vv) {
            if ($v == $vv) { // compare keys only if value are the same
                $compare = call_user_func_array($compare_func, array($k, $kk));
                if ($compare == 0) {
                    continue 3; // value should not be added to the result
                }
            }
        }
    }
    $result[$k] = $v;
}

这里的实际源 (每<一个href=\"http://stackoverflow.com/questions/29421414/why-does-array-diff-uassoc-compares-keys-whose-value-do-not-match#comment47016778_29422485\">comment)

这code执行比较功能的方式不应该输,我们看到的结果。的foreach不能够来回移动的键(AFAIK ???),因为似乎是在第一密钥此处的顺序的情况下:

The way this code executes the compare function should not be outputting the result we see. Foreach is not able to move back and forth in the keys (AFAIK???), as seems to be the case in the order of the first key here:


1 : 2
3 : 1
2 : 1

此外,它不应该检查键如果值不匹配,那么为什么做这些检查:

moreover, it shouldn't check the keys if the value do not match, so why do all these are checked:


1 : 2
3 : 1
2 : 1
3 : 2
etc...

如何能最上面的foreach()在源$ C ​​$ C回环往复通过钥匙?!

为什么键,其值不匹配仍然比较?

做foreach循环实际上仍能继续执行时,他们已经继续 D?

Do foreach loops actually continue executing even when they've been continued?

这是并发的例子可以call_user_func_array某种方式推出,实际执行回声($ A:$ B&LT; BR /&gt;中); 不在他们的相同顺序上马??

Is this an example of concurrency? can call_user_func_array somehow be launched and actually execute the echo("$a : $b<br/>"); of the compare function not in the same order they were "launched"??

推荐答案

我相信你精确定位的错误,我的朋友。我只是跑在你提到的问题code,果然,它相比,这是不一样的值的键。不过,我想测试,如果源$ C ​​$ C本身包含的错误,所以我增加了的官方消息array_diff_uassoc 这个要顶他的code,内我自己的命名空间:

I believe you've pinpointed a bug, my friend. I just ran the code in the question you referenced, and sure enough, it compared keys for values that weren't the same. However, I wanted to test if the source code itself contained the mistake, so I added the official source for array_diff_uassoc this to the top his code, inside my own namespace:

<?php

namespace mine;

// Code obtained from https://pear.php.net/reference/PHP_Compat-latest/__filesource/fsource_PHP_Compat__PHP_Compat-1.6.0a3CompatFunctionarray_diff_uassoc.php.html

function array_diff_uassoc()


{

    // Sanity check

    $args = func_get_args();

    if (count($args) < 3) {

        user_error('Wrong parameter count for array_diff_uassoc()', E_USER_WARNING);

        return;

    }



    // Get compare function

    $compare_func = array_pop($args);

    if (!is_callable($compare_func)) {

        if (is_array($compare_func)) {

            $compare_func = $compare_func[0] . '::' . $compare_func[1];

        }

        user_error('array_diff_uassoc() Not a valid callback ' .

            $compare_func, E_USER_WARNING);

        return;

    }



    // Check arrays

    $array_count = count($args);

    for ($i = 0; $i !== $array_count; $i++) {

        if (!is_array($args[$i])) {

            user_error('array_diff_uassoc() Argument #' .

                ($i + 1) . ' is not an array', E_USER_WARNING);

            return;

        }

    }



    // Compare entries

    $result = array();

    foreach ($args[0] as $k => $v) {

        for ($i = 1; $i < $array_count; $i++) {

            foreach ($args[$i] as $kk => $vv) {

                if ($v == $vv) {

               //   echo ("$v\n");
                    // echo ("$vv\n");
               //   echo ("$k\n");
                    // echo ("$kk\n");
                    // die();

                    $compare = call_user_func_array($compare_func, array($k, $kk));

                    if ($compare == 0) {

                        continue 3;

                    }

                }

            }

        }



        $result[$k] = $v;

    }

    return $result;

}

class chomik {

    public $state = 'normal';
    public $name = 'no name';

    public function __construct($name) {
        $this->name = $name;
    }

    public function __toString() {
        return $this->name . " - " . $this->state;
    }
}

function compare($a, $b) {
    echo("$a : $b\n");
    if($a != $b) {
        return 0;
    }
    else return 1;
}

$chomik = new chomik('a');
$a = array(5, $chomik, $chomik, $chomik);
$b = array($chomik, 'b', 'c', 'd');
array_diff_uassoc($a, $b, 'mine\compare');

这时候,只为那名相同的值相比键:

This time, it only compared keys for values that were equal:

1 : 0
2 : 0
3 : 0

奇怪了,是吧?

这篇关于为什么array_diff_uassoc比较键,其价值不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆