2012-01-04 3 views
0

Я пытаюсь сортировать свой массив по размеру дочернего массива, и я использую его с uasort, но код уродливый и выглядит так, как будто это могло быть сделано лучше, так как есть много дублирующего кода.Улучшение массива сортировки по размеру дочернего массива

Как я могу улучшить этот тип переключателя/случая, который я создал?

switch ($this->view->sort_key_num) { 
    case 1: // Date 
     if ($this->view->sort_key_type == 1) 
     krsort($this->view->content); 
    break; 
    case 2: // Likes 
    function sort_like(&$a, &$b) { return ($a['likes'] > $b['likes']) ? 1 : -1; } 
    uasort($this->view->content, 'sort_like'); 
    if ($this->view->sort_key_type == 1) 
     $this->view->content = array_reverse($this->view->content); 
    break; 
    case 3: // new content 
    function sort_entries(&$a, &$b) { return ($a['newcontent'] > $b['newcontent']) ? 1 : -1; } 
    uasort($this->view->content, 'sort_entries'); 
    if ($this->view->sort_key_type == 1) 
     $this->view->content = array_reverse($this->view->content); 
    break; 
    case 4: // comments 
    function sort_comments(&$a, &$b) { return ($a['comments'] > $b['comments']) ? 1 : -1; } 
    uasort($this->view->content, 'sort_comments'); 
    if ($this->view->sort_key_type == 1) 
     $this->view->content = array_reverse($this->view->content); 
    break; 
    case 5: // facebook 
    function sort_facebook(&$a, &$b) { return ($a['facebook'] > $b['facebook']) ? 1 : -1; } 
    uasort($this->view->content, 'sort_facebook'); 
    if ($this->view->sort_key_type == 1) 
     $this->view->content = array_reverse($this->view->content); 
    break; 
    case 6: // twitter 
    function sort_twitter(&$a, &$b) { return ($a['twitter'] > $b['twitter']) ? 1 : -1; } 
    uasort($this->view->content, 'sort_twitter'); 
    if ($this->view->sort_key_type == 1) 
     $this->view->content = array_reverse($this->view->content); 
    break; 
    case 7: // email 
    function sort_email(&$a, &$b) { return ($a['email'] > $b['email']) ? 1 : -1; } 
    uasort($this->view->content, 'sort_email'); 
    if ($this->view->sort_key_type == 1) 
     $this->view->content = array_reverse($this->view->content); 
    break; 
    case 8: // google 
    function sort_google(&$a, &$b) { return ($a['google'] > $b['google']) ? 1 : -1; } 
    uasort($this->view->content, 'sort_google'); 
    if ($this->view->sort_key_type == 1) 
     $this->view->content = array_reverse($this->view->content); 
    break; 
    case 10: // views 
    function sort_views(&$a, &$b) { return ($a['views'] > $b['views']) ? 1 : -1; } 
    uasort($this->view->content, 'sort_views'); 
    if ($this->view->sort_key_type == 1) 
     $this->view->content = array_reverse($this->view->content); 
    break; 
} 

ответ

1

Я не сделал все тестовые случаи и не читать их все подробно, но я думаю, что это будет хорошая оптимизация кода ...

class customSorter { 
    private $sortCrit = NULL; 
    public function __construct($criteria){ 
      $this->sortCrit = $criteria; 
    } 
    public function sort(&$a, &$b) { return ($a[$this->sortCrit] > $b[$this->sortCrit]) ? 1 : -1; } 
} 

switch ($this->view->sort_key_num) { 
    case 1: // Date 
     if ($this->view->sort_key_type == 1){ 
      krsort($this->view->content); 
     } 
     break; 

    case 2: // Likes 
     uasort($this->view->content, array(new customSorter('likes'), 'sort')); 
     break; 

    case 3: // new content 
     uasort($this->view->content, array(new customSorter('newcontent'), 'sort')); 
     break; 

    case 4: // comments 
     uasort($this->view->content, array(new customSorter('comments'), 'sort')); 
     break; 

    case 5: // facebook 
     uasort($this->view->content, array(new customSorter('facebook'), 'sort')); 
     break; 
} 

//Reverse the sort? 
if ($this->view->sort_key_type == 1){ 
    $this->view->content = array_reverse($this->view->content); 
} 
1

Вы могли бы создать класс для сортировать по type.

class Sorter { 
    private $type; 
    private $content; 
    public function __construct($content) 
    { 
     $this->content = $content; 
    } 
    public function sort($type) 
    { 
     $this->type = $type; 
     uasort($this->content, function ($a,$b) { 
      return $b[$this->type] - $a[$this->type]; 
     }); 
    } 
} 

Теперь я удалил часть Date, поскольку это был особый случай. Вместо этого мы обрабатываем деталь Date отдельно.

if ($this->view->sort_key_type == 1 && $this->view->sort_key_num == 1) { 
    krsort($this->view->content); 
} 

Если выясняется, что это не дата, мы работаем, мы создаем экземпляр класса сортировщика, который мы определили раньше, и кормить его данные - обратите внимание, как это делается путем ссылки.

else { 
    $sorter = new Sorter(&$this->view->content); 
    switch ($this->view->sort_key_num) { 
     case 2: $sorter->sort('likes'); break; 
     case 3: $sorter->sort('newcontent') break; 
     case 4: $sorter->sort('comments'); break; 
     case 5: $sorter->sort('facebook'); break; 
      ... 
    } 
} 

В вашем старом коде, вы бы изменить ваш массив в конце, но это не является необходимым, так как я отменил свой метод сравнения (тот, который вы даете uasort), так что код будет отсортированы в обратном порядке.

+0

Непостижимо, что этот код запускается на сервере с php php. 5.2 не поддерживает замыкания, подобные этому пользователю. Хорошая работа, хотя, я все еще застрял в php 5.2, поэтому я не думал о закрытии. Похоже на мой, но с 5.3 саваром ... –

+0

@MathieuDumoulin Спасибо за подсказку, не знал, что анонимные функции не были реализованы раньше этого. – kba

Смежные вопросы