@dimone73

Неправильная сортировка PHP, как исправить?

PHP 5.0
Код сортирует кодеки, однако если кодеков больше 10, то нижние четыре кодека перескакивают наверх и становятся после 1,2.
Например

G.711a
G.729
lpc10
G.723.1
G.726
GSM
ADPCM
speex
G.722.1
G.722.1C
G.726.AAL2
G.711u
G.722
ILBC30

в следующий раз выдает:
G.711a
G.729
G.726.AAL2
G.711u
G.722
ILBC30
lpc10
G.723.1
G.726
GSM
ADPCM
speex
G.722.1
G.722.1C
и так далее: первые два кодека остаются на месте, остальные как патроны в барабане по 4 крутятся.

Код - сортировщик
$my_cmpr = 0;

    interface ICodecComparator {

        public function cmp($a, $b);
    }

    class CodecComparator implements ICodecComparator {

        private $ord_seq = '';

        public function __construct($seq) {
            $this->ord_seq = $seq;
        }

        public function cmp($a, $b) {
            $a_ord_seq_ind = array_search($a->nameid, $this->ord_seq);
            $b_ord_seq_ind = array_search($b->nameid, $this->ord_seq);
            if (($a_ord_seq_ind === FALSE) && ($b_ord_seq_ind === FALSE)) {
                return strcmp($a->hrn, $b->hrn);
            } else {
                if ($b_ord_seq_ind === FALSE) {
                    return -1;
                } else {
                    if ($a_ord_seq_ind === FALSE) {
                        return 1;
                    } else {
                        return strcmp($a_ord_seq_ind, $b_ord_seq_ind);
                    }
                }
            }
        }

    }

    class CodecComparatorFabric {

        public static function Create($ord_seq) {
            return new CodecComparator($ord_seq);
        }

    }

    function my_cmp($a, $b) {
        global $my_cmpr;
        return $my_cmpr->cmp($a, $b);
    }

Запрос на сортировку:
<ul>
                                                            <?php
$my_codecs = $db->query("SELECT codecs.nameid, codecs.hrn FROM codecs WHERE codecs.type = 'audio'")->fetchAll(PDO::FETCH_OBJ);
$my_seq = explode(",", $arr->allow);
$my_cmpr = CodecComparatorFabric::Create($my_seq);
usort($my_codecs, "my_cmp");
foreach ($my_codecs as $k => $v) {
?>
<li>&nbsp;<input type="checkbox" <?php if (in_array($v->nameid, $my_seq)) echo 'checked="checked"'; ?> />
<?php
echo $v->hrn . '</li>';
 }
?>
</ul>

Такое впечатление, что с индексами при сортировке путаница, но проверить на получается.
Есть еще 4 видеокодека, сортируются аналогично, но поскольку их мало, сортировка корректно отрабатывает.
  • Вопрос задан
  • 94 просмотра
Решения вопроса 1
toxa82
@toxa82
Ох и дичь. Еще и на php 15-тилетней давности. Подозреваю что у вас может меняться массив с разрешенными кодеками, та и непонятно откуда берется $arr->allow. Ну и список кодеков которых нет в списке он будет пихать в самый вверх или самый низ.
А проблема с числом больше 10 в том что нужно заменить "return strcmp($a_ord_seq_ind, $b_ord_seq_ind);" на "return $a_ord_seq_ind - $b_ord_seq_ind;", у вас же тут индексы из массива, зачем вы их как строки сравниваете.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы