Сортировать массив целых чисел по частоте элементов. Если частота двух элементов одинакова, они будут напечатаны в порядке возрастания - PullRequest
0 голосов
/ 03 июля 2019

Например, , входной массив равен [9,1,9,1,3,9,1,2,9], выходной массив будет [9,9,9,9,1,1, 1,2,3].

Вот что я попробовал ниже, но не дал ожидаемого результата:

$array = [9,1,9,1,3,9,1,2,9];
$values = array_count_values($array);
arsort($values);
$popular = array_keys($values);

print_r(array_values($popular));

foreach ($values as $key => $val) {
    echo $key.", ";
}

Вывод:

Array
(
    [0] => 9
    [1] => 1
    [2] => 3
    [3] => 2
)
9, 1, 3, 2,

Ответы [ 3 ]

1 голос
/ 03 июля 2019

Если мы зациклим array_count_values, то мы сможем убедиться, что они идут в правильном порядке.
Когда есть два одинаковых числа, я нахожу все то же самое с array_intersect, затем обращаюсь к ним и добавляю в правильном порядке.

$array = [9,1,9,1,3,9,1,2,9];
$values = array_count_values($array);
arsort($values);
//var_dump($values);

$result =[];
$same = [];
foreach($values as $key => $val){
    if(!in_array($key, array_keys($same))){
        if(next($values) != $val){
            $result = array_merge($result, array_fill(0, $val, $key));
        }else{
            $same = array_intersect($values, [$val]);
            ksort($same);
            foreach($same as $skey => $val){
                $result = array_merge($result, array_fill(0, $val, $skey));
            }
            //var_dump($same);
        }
    }
}

var_dump($result);

https://3v4l.org/sk44Q

0 голосов
/ 03 июля 2019

Вы можете использовать эту последовательность:

$arrayCounts = array_count_values($array);
usort($array, function ($a, $b) use ($arrayCounts) {
    return $arrayCounts[$b] - $arrayCounts[$a] ?: $a - $b; 
});

Теперь $array отсортировано по запросу.

Функция обратного вызова, передаваемая в качестве аргумента usort, должна возвращать отрицательное число, когда два элемента $a и $b должны оставаться в этом порядке (слева направо), или положительное число, когда они должны быть обратным. 0, когда это не имеет значения.

Числовое выражение, которое возвращается в этой конкретной функции обратного вызова, вычитает частоты $a и $b. Если $b встречается чаще, то это вычитание является положительным, и это возвращается. Точно так же, если вычитание отрицательно, то это отрицательное значение возвращается. Теперь, когда частоты равны, включается оператор ?: и выражение после него оценивается. Это другое вычитание также приводит к положительному или отрицательному значению на основе самого исходного значения. Так что $a - $b будет отрицательным, когда $a < $b, что означает, что порядок может остаться таким, как есть (зная, что мы уже выяснили, что их частоты были равны).

0 голосов
/ 03 июля 2019

Попробуйте usort в сочетании с array_count (php> = 7.0):

$array = [9,1,9,1,3,9,1,2,9];

$arrayCounts = array_count_values($array);

usort($array, function ($a, $b) use ($arrayCounts) {
    $countA = $arrayCounts[$a] ?? 0;
    $countB = $arrayCounts[$b] ?? 0;
    if ($countA == $countB) {
       return $a == $b ? 0 : ($a < $b ? -1 : 1);
    }
    return ($countA > $countB) ? -1 : 1;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...