开发者

Sorting an array based on occurrence

开发者 https://www.devze.com 2023-02-04 06:59 出处:网络
How can I sort an array based on a key\'s value occurrence and then return a unique array (sorted). Consider the example below:

How can I sort an array based on a key's value occurrence and then return a unique array (sorted). Consider the example below:

$broken_links[] = array("page_id" => 1, "reported_by" => "xyz");
$broken_links[] = array("page_id" => 2, "reported_by" => "xyz");
$broken_links[] = array("page_id" => 1, "reported_by" => "xyz");
$broken_links[] = array("page_id" => 3, "reported_by" => "xyz");
$broken_links[] = array("page_id" => 1, "reported_by" => "xyz");
$broken_links[] = array("page_id" => 10, "reported_by" => "xyz");
$broken_links[] = array("page_id" => 2, "reported_by" => "xyz");

Also is it possible for sorted new sorted unique array to somehow include the occurance so that the final array is:

$broken_links[] 开发者_JAVA百科= array("page_id" => 1, "reported_by" => "xyz", "reported_times" => 3);


To sort broken links based on page_id:

function sort_broken_links($a, $b) {
    return $a["page_id"] - $b["page_id"];
}

usort($broken_links, 'sort_broken_links');

I imagine you could use some of PHP's array functions like array_unique() or array_walk() to modify the sorted array to contain reported_times. But to keep it simple, I'll just create an array with the frequencies of each broken link record (sorted as above):

$freq = array();

foreach ($broken_links as $link) {
    if (!isset($freq[$link["page_id"]])) {
        $freq[$link["page_id"]] = $link;
        $freq[$link["page_id"]]["reported_times"] = 0;
    }

    $freq[$link["page_id"]]["reported_times"]++;
}


Adanced array sorting can be done with array_multisort, especially by using the second arg with an array.

I think you're in case of the 3rd example, with one more element, you do not want a simple sort but to sort by the number of occurences. Here if you can have a second array containing the page_id keys, but sorted by occurences, then you'll obtain the whole array sorted by ocurences.

So the problem is to get the list base_id sorted by occurences. this should be available with: array_count_values followed by a simple sort.

edit: example: in fact we do not need a sort but we need to feed a complete index.

$broken_links[] = array("page_id" => 1, "reported_by" => "xyz1");
$broken_links[] = array("page_id" => 2, "reported_by" => "xyz2");
$broken_links[] = array("page_id" => 1, "reported_by" => "xyz3");
$broken_links[] = array("page_id" => 3, "reported_by" => "xyz4");
$broken_links[] = array("page_id" => 55, "reported_by" => "foo");
$broken_links[] = array("page_id" => 1, "reported_by" => "xyz5");
$broken_links[] = array("page_id" => 10, "reported_by" => "xyz6");
$broken_links[] = array("page_id" => 2, "reported_by" => "xyz7");
$broken_links[] = array("page_id" => 55, "reported_by" => "foo");
$broken_links[] = array("page_id" => 55, "reported_by" => "foo");

$pages=array();
foreach ($broken_links as $key => $row) {
    $pages[$key]  = $row['page_id'];
}
//echo "page_id list:\n";print_r($pages);
$pagesidxshort=array_count_values($pages);
//echo "page_id occurences:\n"; print_r($pagesidxshort);
foreach ($pages as $key => $val) {
    $pagesidx[$key]=$pagesidxshort[ $pages[$key] ];
}
//echo "page_id to sort by occurence:\n";print_r($pagesidx);
// here broken links is sorted with same sort as $pagesidx
array_multisort($pagesidx,SORT_DESC,$broken_links);
//echo "Our initial array sorted by occurence of page_id:\n";//print_r($broken_links);

outputs (with debug uncommented)

page_id list:
Array
    [0] => 1
    [1] => 2
    [2] => 1
    [3] => 3
    [4] => 55
    [5] => 1
    [6] => 10
    [7] => 2
    [8] => 55
    [9] => 55
page_id occurences:
Array
    [1] => 3
    [2] => 2
    [3] => 1
    [55] => 3
    [10] => 1
page_id to sort by occurence:
Array
    [0] => 3
    [1] => 2
    [2] => 3
    [3] => 1
    [4] => 3
    [5] => 3
    [6] => 1
    [7] => 2
    [8] => 3
    [9] => 3
Our initial array sorted by occurence of page_id:
Array
    [0] => Array [page_id] => 1  [reported_by] => xyz1
    [1] => Array [page_id] => 1  [reported_by] => xyz3
    [2] => Array [page_id] => 1  [reported_by] => xyz5
    [3] => Array [page_id] => 55 [reported_by] => foo
    [4] => Array [page_id] => 55 [reported_by] => fo
    [5] => Array [page_id] => 55 [reported_by] => foo
    [6] => Array [page_id] => 2  [reported_by] => xyz2
    [7] => Array [page_id] => 2  [reported_by] => xyz7
    [8] => Array [page_id] => 3  [reported_by] => xyz4
    [9] => Array [page_id] => 10 [reported_by] => xyz6


function countErrors(array $arr) {
    $new_arr = array();

    foreach ($arr as $val) {
        if (!array_key_exists($val['page_id'], $new_arr)) {
            $new_arr[$val['page_id']] = $val;
            $new_arr[$val['page_id']]['reported_times'] = 1;
        }
        else {
            $new_arr[$val['page_id']]['reported_times']++;
        }
    }

    usort($new_arr, 'sortErrors');

    return $new_arr;
}

function sortErrors($a, $b) {
    return $a['reported_times'] < $b['reported_times'];
}


$broken_links[] = array("page_id" => 1, "reported_by" => "xyz");
$broken_links[] = array("page_id" => 2, "reported_by" => "xyz");
$broken_links[] = array("page_id" => 1, "reported_by" => "xyz");
$broken_links[] = array("page_id" => 3, "reported_by" => "xyz");
$broken_links[] = array("page_id" => 1, "reported_by" => "xyz");
$broken_links[] = array("page_id" => 10, "reported_by" => "xyz");
$broken_links[] = array("page_id" => 2, "reported_by" => "xyz");


$fixed = countErrors($broken_links);
0

精彩评论

暂无评论...
验证码 换一张
取 消