Сглаживание массива данных PHP - PullRequest
0 голосов
/ 10 июля 2009

У меня есть массив:

Array
(
    [1] => 25
    [2] => 50
    [3] => 25
)

Я бы хотел сделать это:

Array
(
    [1] => 50
    [2] => 50
)

Чтобы сделать это, я разделил среднее значение между 1 и 3. Это самый простой пример, где разделение составляет 50,50. Я хотел бы иметь возможность сократить массив из 15 элементов до 6 элементов.

Есть идеи?

Дополнительные примеры [10, 15, 20, 25] Сокращено до двух элементов: 25 (10 + 15), 45 (20 + 25) [10, 10, 10, 10, 11] Сокращено до двух элементов: 25 (10 + 10 + (10/2)), 26 ((10/2) + 10 + 11)

Ответы [ 3 ]

1 голос
/ 11 июля 2009

Проведя дополнительные тесты решения Питера, я заметил, что оно не дало мне того, что я ожидал, если уменьшение до размера нечетное число. Вот функция, которую я придумал. Он также раздувает наборы данных, которые меньше запрашиваемого размера.

   <?php
        function reduceto($data,$r) {
            $c = count($data);

            // just enough data
            if ($c == $r) return $data;

            // not enough data
            if ($r > $c) {
                $x = ceil($r/$c);
                $temp = array();
                foreach ($data as $v) for($i = 0; $i < $x; $i++) $temp[] = $v;
                $data = $temp;
                $c = count($data);
            }

            // more data then needed
            if ($c > $r) {
                $temp = array();
                foreach ($data as $v) for($i = 0; $i < $r; $i++) $temp[] = $v;
                $data = array_map('array_sum',array_chunk($temp,$c));
            }
            foreach ($data as $k => $v) $data[$k] = $v / $r;
            return $data;
        }
    ?>
0 голосов
/ 10 июля 2009

Вот мой удар по твоему вопросу

<code><pre>
<?php

class Thingy
{
  protected $store;
  protected $universe;

  public function __construct( array $data )
  {
    $this->store = $data;
    $this->universe = array_sum( $data );
  }

  public function reduceTo( $size )
  {
    //  Guard condition incase reduction size is too big
    $storeSize = count( $this->store );
    if ( $size >= $storeSize )
    {
      return $this->store;
    }

    //  Odd number of elements must be handled differently
    if ( $storeSize & 1 )
    {
      $chunked = array_chunk( $this->store, ceil( $storeSize / 2 ) );
      $middleValue = array_pop( $chunked[0] );

      $chunked = array_chunk( array_merge( $chunked[0], $chunked[1] ), floor( $storeSize / $size ) );

      //  Distribute odd-man-out amonst other values
      foreach ( $chunked as &$chunk )
      {
        $chunk[] = $middleValue / $size;
      }
    } else {
      $chunked = array_chunk( $this->store, floor( $storeSize / $size ) );
    }

    return array_map( 'array_sum', $chunked );
  }

}

$tests = array(
    array( 2, array( 25, 50, 25 ) )
  , array( 2, array( 10, 15, 20, 25 ) )
  , array( 2, array( 10, 10, 10, 10, 11 ) )
  , array( 6, array_fill( 0, 15, 1 ) )
);

foreach( $tests as $test )
{
  $t = new Thingy( $test[1] );
  print_r( $t->reduceTo( $test[0] ) );
}

?>
0 голосов
/ 10 июля 2009

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

(Здесь я предполагаю, что вы будете использовать второй массив, но вы можете удалить ненужный, если предпочитаете его таким образом).

...