Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort PHP Array by number of Appearances

Tags:

arrays

php

In short I'd like to order an array by the number of times each member turns up, then remove duplicates.

So this:

$array = array('s', 'h', 'c', 'b', 'a', 'b', 'd', 'e', 'f', 'f', 'g')

Would first be ordered:

('b', 'b', 'f', 'f', 's', 'h', 'c', 'a', 'd', 'e', 'g')

And then have the duplicates removed:

$array = array_unique($array);

And look like this:

('b', 'f', 's', 'h', 'c', 'a', 'd', 'e', 'g')

So, how do I do this? Thanks in advance.

like image 480
Alfo Avatar asked Feb 20 '23 20:02

Alfo


2 Answers

A quick way to do it would be to build an array/map that counts each instance of each letter/entry in the original array, sorts the counted one, and then gets the unique values (in order) from the sorted list.

An example implementation would be:

<?php
$unsorted = array('a', 'b', 'c', 'b', 'd', 'e', 'f', 'f', 'g');

// build an array that "counts" each instance/entry
$count = array();
foreach ($unsorted as $key) {
    if (!isset($count[$key])) $count[$key] = 0;
    $count[$key]++;
}
// sort the counted array in reverse order (to be "descending")
arsort($count, SORT_NUMERIC);

// copy each of the keys of `$count`, in-order, into a new array
$sorted = array();
foreach ($count as $key=>$count) $sorted[] = $key;

print_r($sorted);
?>

This gives the output:

Array( [0] => f [1] => b [2] => e [3] => g [4] => d [5] => c [6] => a )

This does not preserve the order of which letter(s) it sees first, it really just sorts them based on the number of times they're in the original array. It could be modified with additional logic to add some other sort-functionality say, to sort alphabetically after sorting by instances.

Edit: The function array_count_values(), used such as $count = array_count_values($unsorted), could replace the whole "counting" loop from above. The output from that function is the exact same as is produced by my loop. Thanks to @Ana for that hint!

like image 97
newfurniturey Avatar answered Feb 22 '23 10:02

newfurniturey


The accepted answer isn't ideal, and actually incorrect as it does not preserve key/value pairings or result in the output the OP posted. An easier way to do this would be the following:

function sortAndUnique($array)
{
  arsort($array);
  $array = array_count_values($array);
  arsort($array, SORT_NUMERIC);
  return $array;
}

This first alphabetizes the array, then sorts by most frequently occurring values, then sorts those values numerically.

like image 34
DylanReile Avatar answered Feb 22 '23 10:02

DylanReile