Разбить массив по значению - PullRequest
3 голосов
/ 26 января 2012

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

$scores = Array
    (
        ["bob"] => 20
        ["Jane"] => 20
        ["Jill"] => 15
        ["John"] => 10
        ["Jacob"] => 5
    )

Я думаю, что мог бы использовать простой срез или фрагмент, ноЯ хотел бы учесть связи и игнорировать любые точки, которые не вписываются в первые три места, например:

$first = Array
    (
        ["bob"] => 20
        ["Jane"] => 20
    )

$second = Array
    (
        ["Jill"] => 15
    )

$third = Array
    (
        ["John"] => 10
    )

Есть идеи?

Ответы [ 3 ]

3 голосов
/ 26 января 2012
  $arr = array(
      "Jacob" => 5,
      "bob" => 20,
      "Jane" => 20,
      "Jill" => 15,
      "John" => 10,
  );
  arsort($arr);
  $output = array();
  foreach($arr as $name=>$score)
  {
      $output[$score][$name] = $score;
      if (count($output)>3) 
      {
          array_pop($output); 
          break;
      }
  }
  $output = array_values($output); 
  var_dump($output);

$ first будет в $ output [0], $ second в $ output [1] и т. Д. Код ограничен тремя первыми местами.

ps: обновлено для работы сгалстук на третьем месте

1 голос
/ 26 января 2012

Я бы сделал что-то вроде:

function chunk_top_n($scores, $limit)
{
  arsort($scores);
  $current_score = null;
  $rank = array();
  $n = 0;

  foreach ($scores as $person => $score)
  {
    if ($current_score != $score)
    {
      if ($n++ == $limit) break;
      $current_score = $score;
      $rank[] = array();
      $p = &$rank[$n - 1];
    }

    $p[$person] = $score;
  }

  return $rank;
}

Он сортирует массив, затем создает пронумерованные группы.Он сломается, как только будет достигнут предел.

Вы можете сделать это с меньшим количеством кода, если вы используете счет в качестве ключа массива, но преимущество вышеупомянутого подхода заключается в том, что он создает массив именно такВы хотите это сделать в первый раз.

Вы также можете передать $scores по ссылке, если не возражаете против сортировки оригинала.

0 голосов
/ 26 января 2012

Вот мой пример:

<code><?php
function array_split_value($array)
{
    $result = array();
    $indexes = array();

    foreach ($array as $key => $value)
    {
        if (!in_array($value, $indexes))
        {
            $indexes[] = $value;
            $result[] = array($key => $value);
        }
        else
        {
            $index_search = array_search($value, $indexes);
            $result[$index_search] = array_merge($result[$index_search], array($key => $value));
        }
    }

    return $result;
}

$scores = Array(
    'bob' => 20, 
    'Jane' => 20, 
    'Jill' => 15, 
    'John' => 10, 
    'Jacob' => 5
);

echo '<pre>';
print_r(array_split_value($scores));
echo '
';?>
...