Более эффективный способ сортировки уникальных значений из массива массивов по вхождению в PHP - PullRequest
0 голосов
/ 04 августа 2020

Каким будет наиболее эффективный PHP способ получить уникальные значения из массива массивов и отсортировать их по количеству вхождений от наиболее частого до наименее значимого?

Пример входного массива:

Array
(
    [0] => Array
        (
            [0] => A
            [1] => B
            [2] => C
            [3] => D
        )
    [1] => Array
        (
            [0] => A
            [1] => C
            [2] => D
        )
    [2] => Array
        (
            [0] => C
            [1] => F
            [2] => X
        )
)

Результатом будет следующий выходной массив:

Array
(
    [0] => C    // 3
    [1] => A    // 2
    [2] => D    // 2
    [3] => B    // 1
    [4] => F    // 1
    [5] => X    // 1
)

Алфавитный порядок значений с одинаковым количеством вхождений не важен.

Пока я объединяю массив массивов :

$all_posts = call_user_func_array( 'array_merge', $results );

Затем создается новый массив, в котором значения становятся ключами. И значения - это количество раз, которое они встречаются в исходном массиве массивов.

$posts_by_count = array();
foreach( $all_posts as $apost ) {
    $posts_by_count[ $apost ] = 0;
    foreach( $results as $tag_posts ) {
        if( in_array( $apost, $tag_posts ) ) {
            $posts_by_count[ $apost ]++;
        }
    }
}

Затем я могу отсортировать по значению

arsort($posts_by_count);

И создать новый массив, в котором ключи снова становятся значениями .

$sorted_posts = array();
foreach($posts_by_count as $k => $v) {
    $sorted_posts[] = $k;
}

pprint( $sorted_posts );

Что было бы более эффективным способом сделать это?

Ответы [ 2 ]

3 голосов
/ 04 августа 2020

Самое простое, что я могу придумать, - это начать с array_merge(), но использовать знак (...) для объединения всех массивов. Затем используйте встроенный array_count_values(), чтобы суммировать значения, а затем arsort(), чтобы отсортировать их ...

$all_posts = array_merge(...$results );
$posts_by_count = array_count_values($all_posts);
arsort($posts_by_count);

Это дает результат ...

Array
(
    [C] => 3
    [A] => 2
    [D] => 2
    [B] => 1
    [F] => 1
    [X] => 1
)

с использованием

print_r(array_keys($posts_by_count));

дает ...

Array
(
    [0] => C
    [1] => A
    [2] => D
    [3] => B
    [4] => F
    [5] => X
)
1 голос
/ 04 августа 2020

Это просто, сначала выполните итерацию для подсчета вхождений, а затем используйте arsort(), чтобы отсортировать его по значению в порядке убывания:

<?php

// sample data
$arr = [
    ['A', 'B', 'C', 'D'],
    ['A', 'C', 'D'],
    ['C', 'F', 'X']
];

// counting
$newArr = [];
foreach ($arr as $subarr) {
    foreach ($subarr as $char) {
        $newArr[$char] = (!array_key_exists($char, $newArr))
            ? 1
            : $newArr[$char] = $newArr[$char] + 1;
    }
}

// sort by value in DESC order
arsort($newArr);

// To get exactly what you want (without counting) just iterate $newArr and writ is as a $flatArr
$flatArr = [];
foreach ($newArr as $index => $item) {
    $flatArr[] = $index;
}

// or with array_keys which _may_ be unstable @see: https://stackoverflow.com/q/10336363/1066240
$flatArrArrayKeys = array_keys($newArr);

// output
$newArrHr = print_r($newArr, 1);
$flatArrHr = print_r($flatArr, 1);

echo "<pre>OUTPUT:

With count:
$newArrHr

As flat array:
$flatArrHr

As flat array with array_keys()
$flatArrArrayKeys
";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...