错误地使用array_multisort()给出正确的结果?
我目前正在触摸一些遗留代码,试图清理它并遇到了一些难题。 我解决这个问题甚至不是关键任务,所以最多只考虑一个运动问题,但它仍然令我困惑。让我好奇。错误地使用array_multisort()给出正确的结果?
此代码:
// dummy data for the sake of testing/abstract visualisation;
// x is thrown in as an experiment:
$workTables = array(
array('x' => 5, 'Name' => 'foo3', 'Update_time' => '2013-04-04 04:40',),
array('x' => 4, 'Name' => 'foo4', 'Update_time' => '2013-04-01 04:40',),
array('x' => 3, 'Name' => 'foo2', 'Update_time' => '2013-04-04 09:40',),
array('x' => 2, 'Name' => 'foo1', 'Update_time' => '2013-04-12 04:40',),
array('x' => 1, 'Name' => 'foo5', 'Update_time' => '2012-12-04 04:40',),
);
// original legacy code:
if (!empty($workTables)) {
$sort = array();
foreach ($workTables as $key => $value) {
$sort[$key]["Update_time"] = $value["Update_time"];
}
array_multisort($workTables, SORT_ASC, SORT_STRING, $sort);
}
...当投掷12个通知( “Notice: Array to string conversion ...
”),作品预期,通过根据Update_time
订货在$workTables
所有元素。
(的“x”列是我的企图排除它有什么关系Name
,这在原代码是一个固定的前缀,后跟一个时间戳的一部分(例如work_table_1367940392
,work_table_1367940395
,...) ,使得通过Name
相当于排序,以通过排序Update_time
)
很明显,因为I don't want to program by coincidence,这是怎么回事最起码要替换为:
// new code:
if (!empty($workTables)) {
$sort = array();
foreach ($workTables as $key => $value) {
$sort[$key] = $value["Update_time"];
}
array_multisort($sort, SORT_ASC, SORT_STRING, $workTables);
}
...这符合的说明array_multisort()
,也做我们想要的,并不会在我们的脸上扔Notices。
但我真正感兴趣的是为什么旧代码的作品(尽管有通知)。
的部分原因似乎是asort()
和共同行为。,其具有(部分地)未公开的特性,他们可以通过根据数组的内容作用与多维数组工作,通过工作从“从左到右”的结构(至少在PHP 5.4.7 (cli)
)...但是...我被困在试图理解什么是$workTables
和$sort
'可互换'。
我想看看PHP的C源代码来弄明白,但我被困在试图了解发生在这里:
/* Do the actual sort magic - bada-bim, bada-boom. */
zend_qsort(indirect, array_size, sizeof(Bucket **), php_multisort_compare TSRMLS_CC);
...因为我的C的知识已经生锈可怕的是,zend_qsort()
本身就是刚刚脱离我的联盟。
任何接受者?
请记住,我不是绝望的答案,所以不要沉溺于此太多时间,但也许别人也喜欢一个谜题? :)
就我个人而言,我已经投入了一些时间,因为我更喜欢彻底理解代码,尤其是当我试图清理它时 - 即使它只是巧合运行的代码。当谈到进一步理解时,我刚刚达到了死胡同,所以stackoverflow似乎是进一步启发的最佳机会。因此,如果你对幕后发生的事情有一个想法(我怀疑这是微不足道的事情,但我忽略了这一点;在我回过头一段时间后,这往往是我的问题),我很乐意听到!:)
据我所知,阵列正在创建和存储在$sort[$key]
。然后,一旦你调用array_multisort()
,它恰好将数组转换回字符串,并使用该字符串作为定义顺序的值进行排序 - 就像警告所述。然后,该字符串被用作订单定义值。
这个转换数组 - >字符串是如何执行的?只是做echo $anArrayValueHere;
没有帮助;它打印出Array
。类似的技巧,echo "" . $anArrayValueHere . "";
也不会产生任何有用的东西。 (但是它们都没有发出通知!)
很有可能使用了serialize()
。假设,让我们看看会习惯的顺序定义值:
#!/usr/bin/php5
<?php
$sort[0]["Update_time"] = '2012-12-04 04:40';
echo serialize($sort[0]);
然后
$ ./php tmp.php
a:1:{s:11:"Update_time";s:16:"2012-12-04 04:40";}
它看起来像关键是充分明确的,产生可用于定义排序次序一样的东西以及只有Update_time
价值会。
我不确定是否使用serialize()
,但如果是,我认为这是解释。
嗯,我没有看到任何'serialize()'的证据(这将是奇怪的'serialize()'抛出转换警告),但是......这也可能是由于我在C代码中完全迷失方向。 :)我相当确定排序本身是由于sort()和co的多维数组处理('sort()'也使用'zend_qsort()'),对我而言,这个奇怪的问题仍然是阵列。 – pinkgothic 2013-05-08 07:22:58
“(但是它们都没有发出通知!)”顺便说一下,在我的机器上并不是这样,但这只是完成的一个旁注。不过,我得说,非常感谢你的刺伤! :)我希望我有不止一个upvote给你。 – pinkgothic 2013-05-08 07:25:01
bada-bim,bada-boom的评论真的给了它。 – raidenace 2013-05-07 16:20:21
@Raidenace:哈哈,我知道,对吗?它解释了*一切*。 :)(公平地说,我认为这是伟大的 - 幽默的评论是一种罕见的(如果含糊不清)高兴看到。) – pinkgothic 2013-05-08 07:15:10