strcmp 等效于 PHP 中的整数 (strcmp)

Posted

技术标签:

【中文标题】strcmp 等效于 PHP 中的整数 (strcmp)【英文标题】:strcmp equivelant for integers (intcmp) in PHP 【发布时间】:2011-02-20 14:39:35 【问题描述】:

所以我们在 php 中得到了这个函数

strcmp(string $1,string $2) // returns -1,0, or 1;

然而,我们没有 intcmp();所以我创建了一个:

function intcmp($a,$b) 
    if((int)$a == (int)$b)return 0;
    if((int)$a  > (int)$b)return 1;
    if((int)$a  < (int)$b)return -1;

这只是感觉很脏。大家觉得呢?

这是通过传入的排序值对 javascript 进行排序的类的一部分。

class JS

    // array('order'=>0,'path'=>'/js/somefile.js','attr'=>array());
    public $javascripts = array(); 
    ...
    public function __toString()
    
        uasort($this->javascripts,array($this,'sortScripts'));
        return $this->render();
    
    private function sortScripts($a,$b)
    
        if((int)$a['order'] == (int)$b['order']) return 0;
        if((int)$a['order'] > (int)$b['order']) return 1;
        if((int)$a['order'] < (int)$b['order']) return -1;
    
    ....

【问题讨论】:

version_compare() 不会成功吗? 对于好奇的人:我有一个用例需要它是 1/0/-1。我有一个对数组进行排序的函数,并且可以有 3 个标准。我对第一个条件的权重大于第二个条件,因此对于字符串我可以使用strcasecmp($a1, $b1) * $factor,但对于整数我必须使用冗长的 if 语句创建一个函数。 这与软件版本字符串比较相关,例如版本 1.3.10 比 1.3.9 更新。这最好通过部分版本字符串的整数比较来执行。 在 php 7 中添加为 <=> "spaceship" operator。例如。 return $a &lt;=&gt; $b。或确保以整数进行比较:return (int)$a &lt;=&gt; (int)$b. 【参考方案1】:

对于字符串

 usort($points, function ($a, $b) use ($orderFlag, $key1, $key2) 
        return strcmp($a[$key1][$key2], $b[$key1][$key2]) * $orderFlag;
    );

orderFlag => 1(升序):-1(降序)

对于数字

usort($points, function ($a, $b) use ($orderFlag, $key1, $key2) 
    return ($a[$key1][$key2] - $b[$key1][$key2]) * $orderFlag;
);

orderFlag => 1(升序):-1(降序)

【讨论】:

【参考方案2】:

为什么要重新发明***? http://php.net/manual/en/function.strnatcmp.php

echo strnatcmp(1, 2) . PHP_EOL; // -1
echo strnatcmp(10, 2) . PHP_EOL; // 1
echo strnatcmp(10.5, 2) . PHP_EOL; // 1 - work with float numbers
echo strnatcmp(1, -2) . PHP_EOL; // 1 - work with negative numbers

在这里测试它: https://3v4l.org/pSANR

【讨论】:

这也适用于只有第一个或第二个参数是字符串的所有情况。 抱歉,这是个玩笑吗?你有两个数字,你通过将它们转换为字符串来比较它们,然后函数将它们转换回整数并比较它们,就像你一开始自己做的那样。【参考方案3】:

纯粹作为一些附加信息,已经有一个接受的 RFC (https://wiki.php.net/rfc/combined-comparison-operator)。

所以,比较函数应该是...

<?php
$data = [...];
usort($data, function($left, $right) return $left <=> $right; );
?>

这里的一些非常好的功能是比较的完成方式与所有其他比较完全相同。所以类型杂耍会按预期发生。

到目前为止,还没有像 __forCompare() 这样的神奇方法来允许对象公开比较值。当前的提议(不同的 RFC)是在比较期间将每个对象注入到每个其他对象中,以便它进行比较 - 这对我来说似乎很奇怪 - 递归和堆栈溢出的潜在机会......!我会认为注入对象的类型进行比较(允许对象能够根据比较的类型表示适当的值)或盲目请求对象可以提供比较的值,会更安全解决方案。

尚未集成到 PHP-NG(目前为 PHP 7),但希望很快就会集成。

【讨论】:

【参考方案4】:

使用以下方式对数据进行排序:

function sortScripts($a, $b)

    return $a['order'] - $b['order'];

如果您想要颠倒的顺序,请使用 $b-$a。

如果有问题的数字超出 PHP 的整数范围,return ($a &lt; $b) ? -1 : (($a &gt; $b) ? 1 : 0) 会更稳健。

【讨论】:

我不得不使用 ($b-$a)*-1 进行逆序。但我离题了。谢谢! 这个实现是broken,就像在许多其他语言中一样。 为了澄清@aioobe 所说的,如果整数超出 php 的整数范围(64 位有符号)并隐式转换为浮点值,则此实现会中断。因此,虽然($a - $b) 显然要快得多,但它不如在所有情况下都有效的($a &lt; $b) ? -1 : (($a &gt; $b) ? 1 : 0) 健壮。 min(max($a - $b, -1), 1) 适用于整数,但如果您还需要处理浮点数并且希望范围 >-1。 .. .. 这也打破了(小)十进制数。因此,最好使用更强大的版本。【参考方案5】:

你可以使用

function intcmp($a,$b)
    
    return ($a-$b) ? ($a-$b)/abs($a-$b) : 0;
    

虽然我完全看不出使用这个功能的意义

【讨论】:

这就像一个魅力!你认为它在课堂环境中有效吗?还是会有更好的实施?我还没有找到一个好的多维数组排序标准!! 这是一个聪明的 oneliner 和所有,但 1 行并不总是比 3 更简单。如果我遇到这段代码只是为了意识到比它所做的只是返回 5 分钟,我会摸不着头脑1/0/-1 与所有这些除法和模数。我会选择原始版本 tbh。 如果遇到减法和除法,您会摸不着头脑吗?认真的吗? 令人毛骨悚然。一个 abs、一个除法和两个减法,来实现一个微不足道的、司空见惯的函数?请像其他人一样做显而易见的事情。你未来的代码读者会感谢你的。【参考方案6】:

必须是 +1 和 -1 吗?如果没有,只需返回(int) $a - (int) $b。我不喜欢其他人推荐的划分,也没有必要检查所有三种情况。如果不大于不等于,则必须小于。

return (int) $a > (int) $b ? 1 : (int) $a == (int) $b ? 0 : -1;

【讨论】:

IMO 堆叠三元运算符是不好的做法。在这种情况下,我们的操作顺序存在问题。更正: return (int) $a > (int) $b ? 1 : ( (int) $a == (int) $b ? 0 : -1 ); PHP 的运算符顺序是否与 C 不同?如果没有添加括号,解释器将如何解析此语句? 是的,PHP 中的三元运算符关联性被破坏了:phpsadness.com/sad/30【参考方案7】:

乍一看,是的,感觉很脏。除了必须有一个的理由,你写的不是仅仅使用实际的==&gt;&lt; 运算符。创建这个函数的动机是什么?

如果是我,我可能会这样做:

$x = $a==$b ? 0 : ($a>$b ? 1 : ($a<$b ? -1 : null));

我意识到这同样丑陋,: null; - 不确定 PHP 是否需要它,或者我是否可以刚刚完成 :;,但我不喜欢它,并且该代码无论如何都不应该执行......如果我知道最初的要求,我想我不会对此感到困惑!

【讨论】:

+1,这里可能没有动机,intcmp 在 PHP 中没有多大意义。 @Andy E 的负责人:我猜测动机是产生与strcmp 相似结果的函数,但我必须了解导致这个想法。 这个想法是为了帮助对 javascripts 多维数组的数组进行排序。【参考方案8】:

我不会称它为 dirty 本身,它似乎足够有效。但我想不出我会在哪里使用该功能。我唯一的建议可能是包含else

function intcmp($a,$b)

    if((int)$a == (int)$b)return 0;
    else if((int)$a  > (int)$b)return 1;
    else if((int)$a  < (int)$b)return -1;

【讨论】:

添加elses 有什么好处吗?至少在我看来,与操作所写的内容相比,它看起来不太可读。

以上是关于strcmp 等效于 PHP 中的整数 (strcmp)的主要内容,如果未能解决你的问题,请参考以下文章

PHP 等效于 .NET/Java 的 toString()

PHP 5.2 等效于后期静态绑定(新静态)?

PHP(或其他 linux 友好)等效于 .Net System.Xml.Linq

PHP: intval() 等价于数字 >= 2147483647

与 Excel 中的 sumif 函数等效的简洁 R 代码 - 特别适用于数据框行

Javascript 等效于 PHP 的 list()