strcmp equivifiant pour les entiers (intcmp) en PHP

donc nous avons eu cette fonction en PHP

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

nous n'avons cependant pas d'intcmp (); J'en ai donc créé un:

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;
}

ça sent juste sale. Que faites vous en pensez, vous?

Cela fait partie d'une classe pour trier les Javascripts par une valeur d'ordre transmise.

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;
    }
    ....
}
51
demandé sur MPelletier 2010-05-18 00:40:22

7 réponses

Triez vos données avec:

function sortScripts($a, $b)
{
    return $a['order'] - $b['order'];
}

utilisez $b - $a si vous voulez l'ordre inversé.

si les nombres en question dépassent la plage entière de PHP, return ($a < $b) ? -1 : (($a > $b) ? 1 : 0) est plus robuste.

90
répondu Nicolas Viennot 2015-02-20 16:46:04

, Vous pourriez utiliser

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

bien que je ne vois pas l'intérêt d'utiliser cette fonction du tout

10
répondu nico 2010-05-17 21:02:53

purement à titre d'information supplémentaire, il y a eu une RFC acceptée pour cette ( https://wiki.php.net/rfc/combined-comparison-operator ).

ainsi, la fonction de comparaison serait le long des lignes de ...

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

une petite caractéristique vraiment agréable ici est que la comparaison est faite exactement de la même manière que toutes les autres comparaisons. Donc la jonglerie de type se produira comme prévu.

encore, il n'y a pas de méthode magique __forCompare() comme pour permettre à un objet d'exposer une valeur de comparaison. La proposition actuelle (un RFC différent) est de faire injecter chaque objet dans chaque autre objet pendant la comparaison afin qu'il fasse la comparaison - ce qui me semble étrange - possibilité potentielle de récursion et de débordement de la pile ... ! J'aurais pensé soit injecter le type d'objet pour la comparaison (permettant à un objet la capacité de représenter des valeurs appropriées en fonction de le type de comparaison) ou une demande aveugle pour une valeur que l'objet peut servir pour la comparaison, aurait été une solution plus sûre.

N'est pas encore intégré dans PHP-NG (PHP 7 pour le moment), mais on espère qu'il le sera bientôt.

6
répondu Richard A Quadling 2015-05-12 09:31:32

pourquoi réinventer la roue? 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

tester ici: https://3v4l.org/pSANR

5
répondu Gabriele Manganello 2016-06-16 13:18:03

Je ne l'appellerais pas sale en soi, cela semble assez valable. Mais je ne sais pas où je pourrais utiliser cette fonction. Ma seule suggestion pourrait être d'inclure 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;
}
3
répondu JYelton 2010-05-17 20:44:18

a-T-elle à être de +1 et de -1? Sinon, retournez (int) $a - (int) $b . Je n'aime pas le diviser que quelqu'un d'autre a recommandé, et il n'y a pas besoin de vérifier pour les trois cas. S'il n'est pas plus grand et pas égal, il doit être moins que.

return (int) $a > (int) $b ? 1 : (int) $a == (int) $b ? 0 : -1;
3
répondu tomlogic 2010-05-17 20:58:23

en un coup d'oeil, oui, ça fait sale. Sauf qu'il doit y avoir une bonne raison que vous avez écrit qu'au lieu de simplement utiliser les réels == , > , et < opérateurs. Quelle a été la motivation de la création de cette fonction?

si c'était moi, je ferais probablement quelque chose comme:

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

je me rends compte que c'est tout aussi laid, et le : null; - pas sûr si PHP l'exige ou si j'aurais pu juste fait :; mais je ne l'aime pas et ce code ne devrait jamais s'exécuter de toute façon... Je pense que je serais beaucoup moins confus à ce sujet si je connaissais les exigences originales!

1
répondu FrustratedWithFormsDesigner 2010-05-17 20:44:36