Aynı nesneleri sayısına göre PHP dizi sipariş

6 Cevap php

Bu şekilde bir dizi sipariş için yine de var mı? Örneğin, eğer bu bir dizi vardı:

$array = array("foo", "bar", "item", "item", "foo", "foo");

Ve ben o "foo", "foo", "foo", "madde", "madde", "bar" olduğunu yapmak için herhangi bir yolu var olduğunu bu yüzden sipariş etmek istedim?

6 Cevap

Bu yapardın?

$array1 = array_count_values($array);
arsort($array1);
var_dump($array1);

verecek

array(3) {
  ["foo"]=>
  int(3)
  ["item"]=>
  int(2)
  ["bar"]=>
  int(1)
}

ya da mutlaka tekrarlanan değerleri olarak onlara ihtiyacım var? evet, sen böyle bir şey için gidebilir:

usort($array,create_function('$a,$b',
    'return $GLOBALS["array1"][$a]<$GLOBALS["array1"][$b];'));

Bu çirkin kod, ama tekniği göstermektedir. Bu php 5.3 kapakları ile iyi görünümlü yapmak da kolaydır, ancak 5.3 üzerinde iseniz bilmiyorum. İşte bu gibi görünecektir:

$acount=array_count_values($array = array("foo", "bar", "item", "item", "foo", "foo"));
usort($array,function($a,$b) use ($acount) { return $acount[$a]<$acount[$b]; });

usort() işe yarayabilir. array_count_values() olsa kullanışlı geliyor. Yapmanız gereken hesaplamalar ile, bu biraz daha net ve verimli olabilir. Tekrarlanan değerler (100 +) bir yeri vardır, ayrıca array_fill() yerine döngü için kullanarak düşünebilirsiniz:

function getSortedGroupArray($array) {
  $return = array();
  $values = array_count_values($array);
  sort($values);
  foreach($values as $count => $value) {
    for($i = 0; $i < $count; ++$i) {
      $return[] = $value;
    }
  }
  return $return
}

Yani, bir, iki ya da üç aşamalı bir süreç olarak yapmak için basit olacağını, oldukça sıradışı ve sıralama süreç.

İlk farklı nesneleri saymak, sonra nesne sayılarını sıralamak ve sıralanan nesne dizisi bundan oluşturmak.

Bu deneyin sağlar:

// First, lets count the number of objects  
$sort_by_term = array();
foreach($array as $string)
{
   if(isset($sort_by_term[$string]))
   {
       $sort_by_term[$string] += 1;
   }
   else
   {
       $sort_by_term[$string] = 1;
   }
}

// Next let's sort them by number
$sort_by_count = array();
foreach($sort_by_term as $term => $count)
{
    $sort_by_count[$count][] = $term;
}

// Now lets combine them
$final_array = array();
foreach($sort_by_count as $count => $term)
{
    while($count > 0)
    {
        $final_array[] = $term;
        $count -= 1;
    }
}

PHP'nin bazı fonksiyonları kullanarak kısaltılmış, ama yapılması gereken ne fikir almak olabilir.

Sen Bir dizide bir değerin göründüğü ile frekansı ile sipariş için aşağıdaki işlevi kullanabilirsiniz:

function array_count_sort(&$array, $direction = 1)
{
    // Could do with a better way of making $counts and $dir available to the
    // sorting function, but this will do for illustrative purposes.
    global $counts, $dir; 
    $counts = array_count_values($array);
    $dir = $direction;

    if (!function_exists('array_count_sort_cmp')) {
        function array_count_sort_cmp($a, $b) {
            global $counts, $dir;

            $c = $counts[$a];
            $d = $counts[$b];

            if ($c == $d) return 0;
            return ($c < $d) ? -$dir : $dir;
        }
    }

    usort($array, 'array_count_sort_cmp');
}

Ve şu şekilde kullanılmaktadır:

$test = array("foo", "bar", "item", "item", "foo", "foo");
print_r($test);
array_count_sort($test);
print_r($test);
array_count_sort($test, -1);
print_r($test);

ki doğuracak

Array
(
    [0] => foo
    [1] => bar
    [2] => item
    [3] => item
    [4] => foo
    [5] => foo
)
Array
(
    [0] => bar
    [1] => item
    [2] => item
    [3] => foo
    [4] => foo
    [5] => foo
)
Array
(
    [0] => foo
    [1] => foo
    [2] => foo
    [3] => item
    [4] => item
    [5] => bar
)