strcmp equivelant for integers (intcmp) in PHP

PhpFunctionIntegerCompare

Php Problem Overview


So we got this function in PHP

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

We Do not however, have an intcmp(); So i created one:

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

This just feels dirty. What do you all think?

this is part of a class to sort Javascripts by an ordering value passed in.

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

Php Solutions


Solution 1 - Php

Sort your data with:

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

Use $b-$a if you want the reversed order.

If the numbers in question exceed PHP's integer range, return ($a < $b) ? -1 : (($a > $b) ? 1 : 0) is more robust.

Solution 2 - Php

You could use

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

Although I don't see the point in using this function at all

Solution 3 - Php

Purely as some additional information, there has been an accepted RFC for this (https://wiki.php.net/rfc/combined-comparison-operator).

So, the comparison function would be along the lines of ...

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

A few really nice feature here is that the comparison is done in exactly the same way as all other comparisons. So type juggling will happen as expected.

As yet, there is no magic __forCompare() like method to allow an object to expose a comparison value. The current proposal (a different RFC) is to have each object be injected into every other object during the comparison so that it does the comparison - something which just seems odd to me - potential opportunity for recursion and stack overflow ... ! I would have thought either injecting the type of object for comparison (allowing an object the ability to represent appropriate values depending upon the type of comparison) or a blind request for a value that the object can serve up for comparison, would have been a safer solution.

Not yet integrated into PHP-NG (PHP 7 at the moment), but hopefully will be soon.

Solution 4 - Php

why reinventing the wheel? 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

Test it here: https://3v4l.org/pSANR

Solution 5 - Php

Does it have to be +1 and -1? If not, just return (int) $a - (int) $b. I don't like the divide that someone else recommended, and there's no need to check for all three cases. If it's not greater and not equal, it must be less than.

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

Solution 6 - Php

At a glance, yes it feels dirty. Except there must be a good reason you wrote that instead of just using the actual ==, >, and < operators. What was the motivation for creating this function?

If it were me, I'd probably just do something like:

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

I realize this is just as ugly, and the : null; - not sure if PHP requires it or if I could have just done :; but I don't like it and that code should never execute anyway... I think I'd be a lot less confused about this if I knew the original requirements!

Solution 7 - Php

> For strings

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

orderFlag => 1 (ascending): -1 (descending)

> For numbers

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

orderFlag => 1 (ascending): -1 (descending)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChase WilsonView Question on Stackoverflow
Solution 1 - PhpNicolas ViennotView Answer on Stackoverflow
Solution 2 - PhpnicoView Answer on Stackoverflow
Solution 3 - PhpRichard A QuadlingView Answer on Stackoverflow
Solution 4 - PhpGabriele ManganelloView Answer on Stackoverflow
Solution 5 - PhptomlogicView Answer on Stackoverflow
Solution 6 - PhpFrustratedWithFormsDesignerView Answer on Stackoverflow
Solution 7 - PhpHimanshu JoshiView Answer on Stackoverflow