【问题标题】:usort not ordering correctly a custom class arrayusort 没有正确排序自定义类数组
【发布时间】:2017-05-31 01:41:42
【问题描述】:

我在使用 usort 函数对我的课程进行排序时遇到问题。我无法正确排序我的列表。 事实上,如果我调用两次我的函数,给我不同的结果!

我将有一个 Insignia 对象数组,其中每个对象都有一个 Categoria 对象列表,我需要按其 ID 属性对 Categoria 列表进行排序。

您可以复制this online tester上的下一个代码进行检查。

class Insignia{
    var $id = 0;
    var $nombre = "";
    var $nombre_en = "";
    var $imagen = "";
    var $id_area = 0;
    var $id_fase = 0;
    var $id_estado = 0;
    var $id_hotel = 0;
    var $editable = 0;
    var $lstCategorias = array();//this array contains a list of Categoria objects

    function __construct($id, $nombre, $nombre_en, $imagen, $id_area, $id_fase, $id_estado, $id_hotel, $lstCategorias = array(), $editable = 1){
        $this->id = $id;
        $this->nombre = $nombre;
        $this->nombre_en = $nombre_en;
        $this->imagen = $imagen;
        $this->id_area = $id_area;
        $this->id_fase = $id_fase;
        $this->id_estado = $id_estado;
        $this->id_hotel = $id_hotel;
        $this->editable = $editable;
        $this->lstCategorias = $lstCategorias;
    }

    public function OrdenarPorMinimoVotos($orden = 'asc'){
        if($orden === 'asc'){
            usort($this->lstCategorias, array("Categoria", "compararMinimoVotosAsc"));
        }
        elseif($orden === 'desc'){
            usort($this->lstCategorias, array("Categoria", "compararMinimoVotosDesc"));
        }       
    }
}

class Categoria{
    var $id = 0;
    var $nombre = '';
    var $nombre_en = '';
    var $color = '';
    var $color_fondo = '';
    var $editable = 0;
    var $minimo_votos = 0;
    var $minimo_ideas = 0;

    function __construct($id, $nombre, $nombre_en, $color, $color_fondo, $minimo_votos, $minimo_ideas, $editable = 1){
        $this->id = (int)$id;
        $this->nombre = $nombre;
        $this->nombre_en = $nombre_en;
        $this->color = $color;
        $this->color_fondo = $color_fondo;
        $this->minimo_votos = (int)$minimo_votos;
        $this->minimo_ideas = (int)$minimo_ideas;
        $this->editable = $editable;
    }

    static function compararMinimoVotosAsc($cat1, $cat2){
        if ($cat1->minimo_votos == $cat2->minimo_votos) {
            $cmp = 0;
        }
        $cmp = ($cat1->minimo_votos < $cat2->minimo_votos) ? -1 : 1;

        return $cmp;
    }

    static function compararMinimoVotosDesc($cat1, $cat2){
        if ($cat1->minimo_votos == $cat2->minimo_votos) {
            return 0;
        }
        return ((int)$cat1->minimo_votos > (int)$cat2->minimo_votos) ? -1 : 1;
    }

    static function compararMinimoIdeas($cat1, $cat2){
        if ($cat1->minimo_ideas == $cat2->minimo_ideas) {
            return 0;
        }
        return ($cat1->minimo_ideas < $cat2->minimo_ideas) ? -1 : 1;
    }
}

//this are my data...
$insignias = unserialize('a:4:{i:0;O:8:"Insignia":10:{s:2:"id";s:1:"1";s:6:"nombre";s:33:"Has conseguido 10 ideas aprobadas";s:9:"nombre_en";s:33:"You had reached 10 approbed ideas";s:6:"imagen";s:14:"fa-thumbs-o-up";s:7:"id_area";s:1:"0";s:7:"id_fase";s:1:"0";s:9:"id_estado";s:1:"0";s:8:"id_hotel";s:1:"0";s:8:"editable";s:1:"0";s:13:"lstCategorias";a:4:{i:0;O:9:"Categoria":8:{s:2:"id";i:1;s:6:"nombre";s:3:"Oro";s:9:"nombre_en";s:4:"Gold";s:5:"color";s:7:"#FFD700";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:150;}i:1;O:9:"Categoria":8:{s:2:"id";i:2;s:6:"nombre";s:5:"Plata";s:9:"nombre_en";s:6:"Silver";s:5:"color";s:7:"#C0C0C0";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:50;}i:2;O:9:"Categoria":8:{s:2:"id";i:3;s:6:"nombre";s:6:"Bronce";s:9:"nombre_en";s:6:"Bronze";s:5:"color";s:7:"#CD7F32";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:10;}i:3;O:9:"Categoria":8:{s:2:"id";i:4;s:6:"nombre";s:4:"Azul";s:9:"nombre_en";s:4:"Blue";s:5:"color";s:7:"#1E90FF";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:1;}}}i:1;O:8:"Insignia":10:{s:2:"id";s:1:"2";s:6:"nombre";s:38:"Has conseguido 100 votos con tus ideas";s:9:"nombre_en";s:40:"You had reached 100 votes for your ideas";s:6:"imagen";s:7:"fa-star";s:7:"id_area";s:1:"0";s:7:"id_fase";s:1:"0";s:9:"id_estado";s:1:"0";s:8:"id_hotel";s:1:"0";s:8:"editable";s:1:"0";s:13:"lstCategorias";a:4:{i:0;O:9:"Categoria":8:{s:2:"id";i:1;s:6:"nombre";s:3:"Oro";s:9:"nombre_en";s:4:"Gold";s:5:"color";s:7:"#FFD700";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:250;s:12:"minimo_ideas";i:0;}i:1;O:9:"Categoria":8:{s:2:"id";i:2;s:6:"nombre";s:5:"Plata";s:9:"nombre_en";s:6:"Silver";s:5:"color";s:7:"#C0C0C0";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:100;s:12:"minimo_ideas";i:0;}i:2;O:9:"Categoria":8:{s:2:"id";i:3;s:6:"nombre";s:6:"Bronce";s:9:"nombre_en";s:6:"Bronze";s:5:"color";s:7:"#CD7F32";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:25;s:12:"minimo_ideas";i:0;}i:3;O:9:"Categoria":8:{s:2:"id";i:4;s:6:"nombre";s:4:"Azul";s:9:"nombre_en";s:4:"Blue";s:5:"color";s:7:"#1E90FF";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:1;s:12:"minimo_ideas";i:0;}}}i:2;O:8:"Insignia":10:{s:2:"id";s:1:"3";s:6:"nombre";s:22:"Has propuesto 50 ideas";s:9:"nombre_en";s:21:"You had send 50 ideas";s:6:"imagen";s:14:"fa-lightbulb-o";s:7:"id_area";s:1:"0";s:7:"id_fase";s:1:"0";s:9:"id_estado";s:1:"0";s:8:"id_hotel";s:1:"0";s:8:"editable";s:1:"0";s:13:"lstCategorias";a:4:{i:0;O:9:"Categoria":8:{s:2:"id";i:1;s:6:"nombre";s:3:"Oro";s:9:"nombre_en";s:4:"Gold";s:5:"color";s:7:"#FFD700";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:50;}i:1;O:9:"Categoria":8:{s:2:"id";i:2;s:6:"nombre";s:5:"Plata";s:9:"nombre_en";s:6:"Silver";s:5:"color";s:7:"#C0C0C0";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:25;}i:2;O:9:"Categoria":8:{s:2:"id";i:3;s:6:"nombre";s:6:"Bronce";s:9:"nombre_en";s:6:"Bronze";s:5:"color";s:7:"#CD7F32";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:10;}i:3;O:9:"Categoria":8:{s:2:"id";i:4;s:6:"nombre";s:4:"Azul";s:9:"nombre_en";s:4:"Blue";s:5:"color";s:7:"#1E90FF";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:1;}}}i:3;O:8:"Insignia":10:{s:2:"id";s:1:"4";s:6:"nombre";s:48:"Has conseguido que se implemente tu primera idea";s:9:"nombre_en";s:43:"You had reached your first implemented idea";s:6:"imagen";s:6:"fa-cog";s:7:"id_area";s:1:"0";s:7:"id_fase";s:1:"0";s:9:"id_estado";s:1:"0";s:8:"id_hotel";s:1:"0";s:8:"editable";s:1:"0";s:13:"lstCategorias";a:4:{i:0;O:9:"Categoria":8:{s:2:"id";i:1;s:6:"nombre";s:3:"Oro";s:9:"nombre_en";s:4:"Gold";s:5:"color";s:7:"#FFD700";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:150;}i:1;O:9:"Categoria":8:{s:2:"id";i:2;s:6:"nombre";s:5:"Plata";s:9:"nombre_en";s:6:"Silver";s:5:"color";s:7:"#C0C0C0";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:50;}i:2;O:9:"Categoria":8:{s:2:"id";i:3;s:6:"nombre";s:6:"Bronce";s:9:"nombre_en";s:6:"Bronze";s:5:"color";s:7:"#CD7F32";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:10;}i:3;O:9:"Categoria":8:{s:2:"id";i:4;s:6:"nombre";s:4:"Azul";s:9:"nombre_en";s:4:"Blue";s:5:"color";s:7:"#1E90FF";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:1;}}}}a:4:{i:0;O:8:"Insignia":10:{s:2:"id";s:1:"1";s:6:"nombre";s:33:"Has conseguido 10 ideas aprobadas";s:9:"nombre_en";s:33:"You had reached 10 approbed ideas";s:6:"imagen";s:14:"fa-thumbs-o-up";s:7:"id_area";s:1:"0";s:7:"id_fase";s:1:"0";s:9:"id_estado";s:1:"0";s:8:"id_hotel";s:1:"0";s:8:"editable";s:1:"0";s:13:"lstCategorias";a:4:{i:0;O:9:"Categoria":8:{s:2:"id";i:1;s:6:"nombre";s:3:"Oro";s:9:"nombre_en";s:4:"Gold";s:5:"color";s:7:"#FFD700";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:150;}i:1;O:9:"Categoria":8:{s:2:"id";i:2;s:6:"nombre";s:5:"Plata";s:9:"nombre_en";s:6:"Silver";s:5:"color";s:7:"#C0C0C0";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:50;}i:2;O:9:"Categoria":8:{s:2:"id";i:3;s:6:"nombre";s:6:"Bronce";s:9:"nombre_en";s:6:"Bronze";s:5:"color";s:7:"#CD7F32";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:10;}i:3;O:9:"Categoria":8:{s:2:"id";i:4;s:6:"nombre";s:4:"Azul";s:9:"nombre_en";s:4:"Blue";s:5:"color";s:7:"#1E90FF";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:1;}}}i:1;O:8:"Insignia":10:{s:2:"id";s:1:"2";s:6:"nombre";s:38:"Has conseguido 100 votos con tus ideas";s:9:"nombre_en";s:40:"You had reached 100 votes for your ideas";s:6:"imagen";s:7:"fa-star";s:7:"id_area";s:1:"0";s:7:"id_fase";s:1:"0";s:9:"id_estado";s:1:"0";s:8:"id_hotel";s:1:"0";s:8:"editable";s:1:"0";s:13:"lstCategorias";a:4:{i:0;O:9:"Categoria":8:{s:2:"id";i:1;s:6:"nombre";s:3:"Oro";s:9:"nombre_en";s:4:"Gold";s:5:"color";s:7:"#FFD700";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:250;s:12:"minimo_ideas";i:0;}i:1;O:9:"Categoria":8:{s:2:"id";i:2;s:6:"nombre";s:5:"Plata";s:9:"nombre_en";s:6:"Silver";s:5:"color";s:7:"#C0C0C0";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:100;s:12:"minimo_ideas";i:0;}i:2;O:9:"Categoria":8:{s:2:"id";i:3;s:6:"nombre";s:6:"Bronce";s:9:"nombre_en";s:6:"Bronze";s:5:"color";s:7:"#CD7F32";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:25;s:12:"minimo_ideas";i:0;}i:3;O:9:"Categoria":8:{s:2:"id";i:4;s:6:"nombre";s:4:"Azul";s:9:"nombre_en";s:4:"Blue";s:5:"color";s:7:"#1E90FF";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:1;s:12:"minimo_ideas";i:0;}}}i:2;O:8:"Insignia":10:{s:2:"id";s:1:"3";s:6:"nombre";s:22:"Has propuesto 50 ideas";s:9:"nombre_en";s:21:"You had send 50 ideas";s:6:"imagen";s:14:"fa-lightbulb-o";s:7:"id_area";s:1:"0";s:7:"id_fase";s:1:"0";s:9:"id_estado";s:1:"0";s:8:"id_hotel";s:1:"0";s:8:"editable";s:1:"0";s:13:"lstCategorias";a:4:{i:0;O:9:"Categoria":8:{s:2:"id";i:1;s:6:"nombre";s:3:"Oro";s:9:"nombre_en";s:4:"Gold";s:5:"color";s:7:"#FFD700";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:50;}i:1;O:9:"Categoria":8:{s:2:"id";i:2;s:6:"nombre";s:5:"Plata";s:9:"nombre_en";s:6:"Silver";s:5:"color";s:7:"#C0C0C0";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:25;}i:2;O:9:"Categoria":8:{s:2:"id";i:3;s:6:"nombre";s:6:"Bronce";s:9:"nombre_en";s:6:"Bronze";s:5:"color";s:7:"#CD7F32";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:10;}i:3;O:9:"Categoria":8:{s:2:"id";i:4;s:6:"nombre";s:4:"Azul";s:9:"nombre_en";s:4:"Blue";s:5:"color";s:7:"#1E90FF";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:1;}}}i:3;O:8:"Insignia":10:{s:2:"id";s:1:"4";s:6:"nombre";s:48:"Has conseguido que se implemente tu primera idea";s:9:"nombre_en";s:43:"You had reached your first implemented idea";s:6:"imagen";s:6:"fa-cog";s:7:"id_area";s:1:"0";s:7:"id_fase";s:1:"0";s:9:"id_estado";s:1:"0";s:8:"id_hotel";s:1:"0";s:8:"editable";s:1:"0";s:13:"lstCategorias";a:4:{i:0;O:9:"Categoria":8:{s:2:"id";i:1;s:6:"nombre";s:3:"Oro";s:9:"nombre_en";s:4:"Gold";s:5:"color";s:7:"#FFD700";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:150;}i:1;O:9:"Categoria":8:{s:2:"id";i:2;s:6:"nombre";s:5:"Plata";s:9:"nombre_en";s:6:"Silver";s:5:"color";s:7:"#C0C0C0";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:50;}i:2;O:9:"Categoria":8:{s:2:"id";i:3;s:6:"nombre";s:6:"Bronce";s:9:"nombre_en";s:6:"Bronze";s:5:"color";s:7:"#CD7F32";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:10;}i:3;O:9:"Categoria":8:{s:2:"id";i:4;s:6:"nombre";s:4:"Azul";s:9:"nombre_en";s:4:"Blue";s:5:"color";s:7:"#1E90FF";s:11:"color_fondo";s:7:"#FFFFFF";s:8:"editable";s:1:"0";s:12:"minimo_votos";i:0;s:12:"minimo_ideas";i:1;}}}}');


$insignias[0]->OrdenarPorMinimoVotos('asc');
echo "asc:<pre>".print_r($insignias[0], true)."</pre>";

我正在调查这几个小时,但我看不出错误在哪里... 谢谢...

【问题讨论】:

  • 但是如果你做 var_dump($insignias[0]) 它仍然会按你的 id 排序。我有四个返回的数组,它们的 id 来自 0、1、2、3 或者你想让它成为 1、2、3、4?在这种情况下,您可以通过+1 进行快速测试
  • 我看不到使用 var_dump 排序的列表...

标签: php arrays class sorting


【解决方案1】:

您的问题是,您在每种情况下都在比较回调中执行第二次比较 - 即使两个 minimo_votos 相等。所以你的比较函数永远不会为相等的对象返回 0。

您应该按照与 compararMinimoIdeas 中相同的方式进行操作。

【讨论】:

  • 是的!这是一个问题。但是现在当我调用 compararMinimoVotosDesc 时,它总是升序排序,而 compararMinimoVotosAsc 总是降序。如果我改变: [code]return ($cat1->minimo_votos minimo_votos) ? -1 : 1;[/code] 到 [code]return ($cat1->minimo_votos > $cat2->minimo_votos) ? -1 : 1;[/code] 也一样!
  • 不,它仍然做错了什么。我已经测试过在开始时将结果随机排序,并且我的函数总是会出现排序错误。我什至看不到错误模式。
  • 请原谅我的最新评论,我是按一个人排序并按另一个人进行测试的。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多