Skip to content

Instantly share code, notes, and snippets.

@jamesmoey
Last active July 24, 2023 07:02
Show Gist options
  • Select an option

  • Save jamesmoey/275faa6d58392fa742b6 to your computer and use it in GitHub Desktop.

Select an option

Save jamesmoey/275faa6d58392fa742b6 to your computer and use it in GitHub Desktop.

Revisions

  1. jamesmoey revised this gist Aug 1, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ExtendedArrayCollection.php
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    <?php
    namespace Ids\Avm\Estimate\ApiBundle\Collections;
    namespace Collections;

    use Doctrine\Common\Collections\ArrayCollection;
    use Symfony\Component\PropertyAccess\PropertyAccess;
  2. jamesmoey revised this gist Feb 10, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ExtendedArrayCollection.php
    Original file line number Diff line number Diff line change
    @@ -164,7 +164,7 @@ public function getStandardDeviation($field)
    * @param string $field
    * @return self
    */
    public function excludeOutlier($median, $sdRange, $field = 'price')
    public function excludeOutlier($median, $sdRange, $field)
    {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $from = $median / 2;
  3. jamesmoey revised this gist Feb 10, 2014. 1 changed file with 166 additions and 115 deletions.
    281 changes: 166 additions & 115 deletions ExtendedArrayCollection.php
    Original file line number Diff line number Diff line change
    @@ -1,130 +1,181 @@
    <?php
    namespace;
    namespace Ids\Avm\Estimate\ApiBundle\Collections;

    use Doctrine\Common\Collections\ArrayCollection;
    use Symfony\Component\PropertyAccess\PropertyAccess;

    class ExtendedArrayCollection extends ArrayCollection {
    class ExtendedArrayCollection extends ArrayCollection
    {

    /**
    * Reduce the collection into a single value.
    *
    * @param \Closure $func
    * @param null $initialValue
    * @return mixed
    */
    public function reduce(\Closure $func, $initialValue = null)
    {
    return array_reduce($this->toArray(), $func, $initialValue);
    }

    /**
    * Apply filter chain
    *
    * @var \Closure[] $chain
    * @return ExtendedArrayCollection
    */
    public function applyFilterChain($chain)
    {
    $collection = $this;
    foreach ($chain as $filter) {
    $collection = $collection->filter($filter);
    }
    return $collection;
    }

    /**
    * Get average
    * @param $field
    * @return float
    */
    public function getAverage($field)
    {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $avg = 0;
    if ($this->count() === 0) return 0;
    $this->forAll(function ($index, $element) use (&$avg, $accessor, $field) {
    $avg += $accessor->getValue($element, $field);
    return true;
    });
    return $avg / $this->count();
    }

    /**
    * Apply filter chain
    *
    * @var \Closure[] $chain
    * @return ExtendedArrayCollection
    */
    public function applyFilterChain($chain)
    {
    $collection = $this;
    foreach ($chain as $filter) {
    $collection = $collection->filter($filter);
    /**
    * Get median.
    *
    * @param $field
    * @return float
    */
    public function getMedian($field)
    {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $iterator = $this->getSortedIteratorOn($field);
    if ($iterator->count() === 0) return 0;
    if ($iterator->count() % 2 === 0) {
    return (
    $accessor->getValue($iterator[ceil($iterator->count() / 2) - 1], $field) +
    $accessor->getValue($iterator[ceil($iterator->count() / 2)], $field)
    ) / 2;
    } else {
    return $accessor->getValue($iterator[floor($iterator->count() / 2)], $field);
    }
    }
    return $collection;
    }

    /**
    * Get average
    * @param $field
    * @return float
    */
    public function getAverage($field) {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $avg = 0;
    if ($this->count() === 0) return 0;
    $this->forAll(function($index, $element) use (&$avg, $accessor, $field) {
    $avg += $accessor->getValue($element, $field);
    return true;
    });
    return $avg / $this->count();
    }
    /**
    * Get absolute median. Make negative into position
    *
    * @param $field
    * @return float
    */
    public function getAbsoluteMean($field) {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $iterator = $this->getSortedAbsoluteIteratorOn($field);
    if ($iterator->count() === 0) return 0;
    if ($iterator->count() % 2 === 0) {
    return (
    abs($accessor->getValue($iterator[ceil($iterator->count() / 2) - 1], $field)) +
    abs($accessor->getValue($iterator[ceil($iterator->count() / 2)], $field))
    ) / 2;
    } else {
    return abs($accessor->getValue($iterator[floor($iterator->count() / 2)], $field));
    }
    }

    /**
    * Get median.
    *
    * @param $field
    * @return float
    */
    public function getMedian($field) {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $iterator = $this->getSortedIteratorOn($field);
    if ($iterator->count() === 0) return 0;
    if ($iterator->count() % 2 === 0) {
    return (
    $accessor->getValue($iterator[ceil($iterator->count()/2)-1], $field) +
    $accessor->getValue($iterator[ceil($iterator->count()/2)], $field)
    ) / 2;
    } else {
    return $accessor->getValue($iterator[ceil($iterator->count()/2)] ,$field);
    public function getSortedAbsoluteIteratorOn($field) {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $iterator = $this->getIterator();
    $iterator->uasort(function ($first, $second) use ($accessor, $field) {
    $firstPrice = abs($accessor->getValue($first, $field));
    $secondPrice = abs($accessor->getValue($second, $field));
    if ($firstPrice == $secondPrice) return 0;
    else return ($firstPrice < $secondPrice ? -1 : 1);
    });
    $list = iterator_to_array($iterator, false);
    return new \ArrayIterator($list);
    }
    }

    /**
    * Get a sorted iterator on a field.
    *
    * @param string $field
    * @return \ArrayIterator
    */
    public function getSortedIteratorOn($field) {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $iterator = $this->getIterator();
    $iterator->uasort(function ($first, $second) use ($accessor, $field) {
    $firstPrice = $accessor->getValue($first, $field);
    $secondPrice = $accessor->getValue($second, $field);
    if ($firstPrice == $secondPrice) return 0;
    else return ($firstPrice < $secondPrice ? -1 : 1);
    });
    $list = iterator_to_array($iterator, false);
    return new \ArrayIterator($list);
    }
    /**
    * Get a sorted iterator on a field.
    *
    * @param string $field
    * @return \ArrayIterator
    */
    public function getSortedIteratorOn($field)
    {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $iterator = $this->getIterator();
    $iterator->uasort(function ($first, $second) use ($accessor, $field) {
    $firstPrice = $accessor->getValue($first, $field);
    $secondPrice = $accessor->getValue($second, $field);
    if ($firstPrice == $secondPrice) return 0;
    else return ($firstPrice < $secondPrice ? -1 : 1);
    });
    $list = iterator_to_array($iterator, false);
    return new \ArrayIterator($list);
    }

    /**
    * Return a new collection with sorted result.
    *
    * @param string $field
    * @return PropertyCollection
    */
    public function getSortedCollection($field) {
    return new self($this->getSortedIteratorOn($field)->getArrayCopy());
    }
    /**
    * Return a new collection with sorted result.
    *
    * @param string $field
    * @return PropertyCollection
    */
    public function getSortedCollection($field)
    {
    return new self($this->getSortedIteratorOn($field)->getArrayCopy());
    }

    /**
    * Get standard deviation.
    *
    * @param $field
    * @return float
    */
    public function getStandardDeviation($field) {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $average = $this->getAverage($field);
    $variance = 0;
    if ($this->count() === 0) return 0;
    $this->forAll(function ($index, $element) use (&$variance, $average, $accessor, $field) {
    $variance += pow($accessor->getValue($element, $field) - $average, 2);
    return true;
    });
    $variance /= $this->count();
    return sqrt($variance);
    }
    /**
    * Get standard deviation.
    *
    * @param $field
    * @return float
    */
    public function getStandardDeviation($field)
    {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $average = $this->getAverage($field);
    $variance = 0;
    if ($this->count() === 0) return 0;
    $this->forAll(function ($index, $element) use (&$variance, $average, $accessor, $field) {
    $variance += pow($accessor->getValue($element, $field) - $average, 2);
    return true;
    });
    $variance /= $this->count();
    return sqrt($variance);
    }

    /**
    * Return a new collection excluding the outlier.
    *
    * @param float $medianPrice The median price.
    * @param float $sdRange The Standard Deviation range.
    * @param string $field
    * @return self
    */
    public function excludeOutlier($medianPrice, $sdRange, $field = 'price') {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $from = $medianPrice - $sdRange;
    $to = $medianPrice + $sdRange;
    return $this->filter(function($e) use ($from, $to, $accessor, $field) {
    $price = 0;
    if ($accessor->getValue($e, $field) !== null) {
    $price = $accessor->getValue($e, $field);
    }
    if ($price > $from && $price < $to) return true;
    else return false;
    });
    }
    }
    /**
    * Return a new collection excluding the outlier.
    *
    * @param $median
    * @param float $sdRange The Standard Deviation range.
    * @param string $field
    * @return self
    */
    public function excludeOutlier($median, $sdRange, $field = 'price')
    {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $from = $median / 2;
    $to = $median + $sdRange;
    return $this->filter(function ($e) use ($from, $to, $accessor, $field) {
    $price = 0;
    if ($accessor->getValue($e, $field) !== null) {
    $price = $accessor->getValue($e, $field);
    }
    if ($price >= $from && $price <= $to) return true;
    else return false;
    });
    }
    }
  4. jamesmoey renamed this gist Oct 16, 2013. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. jamesmoey created this gist Oct 16, 2013.
    130 changes: 130 additions & 0 deletions gistfile1.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    <?php
    namespace;

    use Doctrine\Common\Collections\ArrayCollection;
    use Symfony\Component\PropertyAccess\PropertyAccess;

    class ExtendedArrayCollection extends ArrayCollection {


    /**
    * Apply filter chain
    *
    * @var \Closure[] $chain
    * @return ExtendedArrayCollection
    */
    public function applyFilterChain($chain)
    {
    $collection = $this;
    foreach ($chain as $filter) {
    $collection = $collection->filter($filter);
    }
    return $collection;
    }

    /**
    * Get average
    * @param $field
    * @return float
    */
    public function getAverage($field) {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $avg = 0;
    if ($this->count() === 0) return 0;
    $this->forAll(function($index, $element) use (&$avg, $accessor, $field) {
    $avg += $accessor->getValue($element, $field);
    return true;
    });
    return $avg / $this->count();
    }

    /**
    * Get median.
    *
    * @param $field
    * @return float
    */
    public function getMedian($field) {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $iterator = $this->getSortedIteratorOn($field);
    if ($iterator->count() === 0) return 0;
    if ($iterator->count() % 2 === 0) {
    return (
    $accessor->getValue($iterator[ceil($iterator->count()/2)-1], $field) +
    $accessor->getValue($iterator[ceil($iterator->count()/2)], $field)
    ) / 2;
    } else {
    return $accessor->getValue($iterator[ceil($iterator->count()/2)] ,$field);
    }
    }

    /**
    * Get a sorted iterator on a field.
    *
    * @param string $field
    * @return \ArrayIterator
    */
    public function getSortedIteratorOn($field) {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $iterator = $this->getIterator();
    $iterator->uasort(function ($first, $second) use ($accessor, $field) {
    $firstPrice = $accessor->getValue($first, $field);
    $secondPrice = $accessor->getValue($second, $field);
    if ($firstPrice == $secondPrice) return 0;
    else return ($firstPrice < $secondPrice ? -1 : 1);
    });
    $list = iterator_to_array($iterator, false);
    return new \ArrayIterator($list);
    }

    /**
    * Return a new collection with sorted result.
    *
    * @param string $field
    * @return PropertyCollection
    */
    public function getSortedCollection($field) {
    return new self($this->getSortedIteratorOn($field)->getArrayCopy());
    }

    /**
    * Get standard deviation.
    *
    * @param $field
    * @return float
    */
    public function getStandardDeviation($field) {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $average = $this->getAverage($field);
    $variance = 0;
    if ($this->count() === 0) return 0;
    $this->forAll(function ($index, $element) use (&$variance, $average, $accessor, $field) {
    $variance += pow($accessor->getValue($element, $field) - $average, 2);
    return true;
    });
    $variance /= $this->count();
    return sqrt($variance);
    }

    /**
    * Return a new collection excluding the outlier.
    *
    * @param float $medianPrice The median price.
    * @param float $sdRange The Standard Deviation range.
    * @param string $field
    * @return self
    */
    public function excludeOutlier($medianPrice, $sdRange, $field = 'price') {
    $accessor = PropertyAccess::createPropertyAccessorBuilder()->enableMagicCall()->getPropertyAccessor();
    $from = $medianPrice - $sdRange;
    $to = $medianPrice + $sdRange;
    return $this->filter(function($e) use ($from, $to, $accessor, $field) {
    $price = 0;
    if ($accessor->getValue($e, $field) !== null) {
    $price = $accessor->getValue($e, $field);
    }
    if ($price > $from && $price < $to) return true;
    else return false;
    });
    }
    }