我一直在玩耍,看看是否可以在PHP中设置一个更动态的方法。
usort($dataset, function($a, $b){ return strcasecmp($a[$this->parameters], $b[$this->parameters]); });
此行将按字母降序对数组元素进行排序。但是,如果我们以$a
或$b
交换变量function($a, $b)
和($a[$this->parameters], $b[$this->parameters])
,则会得到相反的效果(降序)。
当我调查此事时,PHP中有诸如变量变量之类的东西。这样的一个例子是
$a="hello";
$$a="oops";
echo($hello);die;
但是,如果我类似地尝试在上面的代码行中实现这一点,则会出现错误。
$first = 'b';
$second = 'a';
usort($dataset, function($$first, $$second){ return strcasecmp($a[$this->parameters], $b[$this->parameters]); });
错误:Parse error: syntax error, unexpected '$', expecting variable (T_VARIABLE)
。
这个想法是能够基于iff语句结果反转效果,以重新定义$first
和$second
变量。否则,人们将需要重复几乎相同的代码。
我错过了什么吗?也许有其他方法可以实现这一目标?
答案 0 :(得分:2)
解析变量的动态名称是在运行时发生的事情,而不是在解释器(即编译)时发生的事情。因此,您不能将其作为您希望能够做的动态参数传递。
鉴于这是不可能的,原因很简单:即使您在编译时设法传递不同的名称,也只能比较一组值。什么会使回调调用不传递a<b
,然后传递a>b
,然后传递a==b
(将它们想象为值)?什么都没有,而且确实会发生。
话虽如此,您可以在传递给最终回调之前尝试验证哪个值较小,但这只会增加一个额外的层,而不是总是以相同的方式进行排序(甚至根本不进行排序):
usort($dataset, function($a, $b)
{
if ($a > $b) {
return $b <=> $a;
}
return $a <=> $b;
});
var_dump($dataset);
// output
array(3) {
[0]=>
int(3)
[1]=>
int(1)
[2]=>
int(7)
}
我完全知道这根本无法解决您的问题。我只是想证明它甚至不会以这种方式工作。
我认为这里的关键事实是您在回调中定义了排序机制,因此您必须确保在该定义中对它进行升序或降序排序,因为这就是它的作用!
还有一点,我认为自spaceship operator起,排序回调就很容易在PHP中创建:
// defines: sort ASC
usort($dataset, function($a, $b) { return $a <=> $b; });
// defines: sort DESC
usort($dataset, function($a, $b) { return $b <=> $a; });
PHP 7.4以后的箭头功能更是如此:
// ASC
usort($dataset, fn($a, $b) => $a <=> $b);
// DESC
usort($dataset, fn($a, $b) => $b <=> $a);
总而言之,我完全理解您的来历,但也许您正在尝试解决甚至根本不存在的问题?
答案 1 :(得分:1)
我想对@ArSeN的一个很好的答案进行扩展,以添加更多的计算机科学上下文来说明为什么这根本不是“一件事”。如果您看一下如何在处理器级别(ASM语言)实现函数,您会很快意识到,传递给函数的参数名称甚至没有在二进制程序中使用。实际上,它们只是使您成为程序员的生活而已。大多数调用约定在stack frame上将函数参数实现为函数之间的空间。在函数内部以它们各自的内存偏移量访问它们。大多数C书籍和课程都会详细介绍这个概念,但是用简单的英语来说,这意味着参数的名称无关紧要,因为最终二进制文件仅使用参数的顺序。它在PHP中已经被抽象得很远,但是,它仍然非常相关,如果您打算以专业水平进行编程,则应该了解一些东西。