Is there any good or standard way of doing this?
Take the following example:
$values = array(
'blue'
, 'blue'
, 'blue'
, 'blue'
, 'green'
, 'red'
, 'yellow'
, 'yellow'
, 'purple'
, 'purple'
, 'purple'
);
I need it to be separated so no two identical values are touching (unless there is no possible solution -- in which case either generating an error, returning false or anything else is acceptable).
Here's the above array (done by hand) but how I am trying to change it:
$values = array(
'blue'
, 'purple'
, 'green'
, 'purple'
, 'blue'
, 'red'
, 'blue'
, 'yellow'
, 'blue'
, 'yellow'
, 'purple'
)
The values won't necessarily be in order in the beginning -- that was just for simplicities sake.
Any ideas? Any code to get me started in the right direction?
This function should do the trick:
function uniq_sort($arr){
if(!count($arr))
return array();
$counts = array_count_values($arr);
arsort($counts);
while(NULL !== ($key = key($counts)) && $counts[$key]){
if(isset($prev) && $prev == $key){
next($counts);
$key = key($counts);
if($key === NULL)
return false;
}
$prev = $result[] = $key;
$counts[$key]--;
if(!$counts[$key])
unset($counts[$key]);
arsort($counts);
reset($counts);
}
return $result;
}
Example usage:
$values = array('blue', 'blue', 'blue', 'blue', 'green', 'red', 'yellow', 'yellow', 'purple', 'purple', 'purple');
print_r(uniq_sort($values));
$values = array('a', 'b', 'b');
print_r(uniq_sort($values));
$values = array(1);
print_r(uniq_sort($values));
$values = array(1, 1, 1, 1, 2, 3, 4);
print_r(uniq_sort($values));
$values = array(1, 1, 1, 1, 2, 3);
var_dump(uniq_sort($values));
And output:
Array
(
[0] => blue
[1] => purple
[2] => blue
[3] => yellow
[4] => blue
[5] => purple
[6] => blue
[7] => purple
[8] => red
[9] => yellow
[10] => green
)
Array
(
[0] => b
[1] => a
[2] => b
)
Array
(
[0] => 1
)
Array
(
[0] => 1
[1] => 3
[2] => 1
[3] => 4
[4] => 1
[5] => 2
[6] => 1
)
bool(false)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With