<commit_before><?php
namespace HodgePodge\Orm;

use HodgePodge\Common;

class Collection extends Common\Collection
{
    public function __get($parameter)
    {
        $list = array();
        foreach($this->container as $item) {
            $value = $item->$parameter;
            if ($item instanceof Model) {
                if ($value instanceof Collection) {
                    $list = array_merge($list, $value->toArray());
                } else {
                    $list[] = $value;
                }
            } else {
                $list[] = $value;
            }
        }
        return new static($list);
    }

    public function __call($name, $arguments)
    {
        $list = array();
        foreach($this->container as $item) {
            if (!method_exists($item, $name)) {
                throw new \BadMethodCallException();
            }
            
            $value = call_user_func_array(array($item, $name),$arguments);
            if ($item instanceof Model) {
                if ($value instanceof Collection) {
                    $list = array_merge($list, $value->toArray());
                } else {
                    $list[] = $value;
                }
            } else {
                $list[] = $value;
            }
        }
        return new static($list);
    }

    public function __construct($array = null)
    {
        if (is_null($array)) $array = array();
        if ($array instanceof Collection) $array = $array->toArray();
        if (!is_array($array)) throw new \InvalidArgumentException('Orm\Collection::__construct() expects an array - ' . gettype($array) . ' given');
        
        $this->container = $array;
    }
    
    public function toArray($value = null, $key = 'id')
    {
        $return = array();
        
        // Empty array?
        if (!count($this->container)) return array();
        
        // If we are dealing with a collection of Model objects then user key/value to extract desired property
        if ($this->container[0] instanceof Model)
        {
            if(!$value) {
                foreach($this->container as $item) {
                    $return[$item->$key] = $item;
                }
                return $return;            
            }
            else
            {
                foreach($this->container as $item) {
                    $return[$item->$key] = $item->$value;
                }
                return $return;
            }
        }
        
        // If we have normal objects or primatives, just return the internal container
        return $this->container;
    }
    
    //////// Collection modifiers ////////
    public function unique()
    {
        $copy = $this->container;
        $clobberlist = [];
        
        foreach($copy as $key => $obj)
        {
            if (in_array($obj->id, $clobberlist))
            {
                unset($copy[$key]);
            }
            else
            {
                $clobberlist[] = $obj->id;
            }
        }
        
        return new static($copy);
    }
    
    public function sort($function)
    {
        $copy = $this->container;
        uasort($copy, $function);
        return new static($copy);
    }
    
    public function natSort($key = null)
    {
        if (!$key)
        {
            return $this->sort(function ($a, $b) {
                return strnatcmp((string) $a, (string) $b);
            });
        }
        else
        {
            return $this->sort(function ($a, $b) {
                return strnatcmp($a->{$key}, $b->{$key});
            });            
        }
    }<commit_msg>Fixed $key not copied into $collection->natSort() closure. (this caused items to be randomly sorted!)<commit_after><?php
namespace HodgePodge\Orm;

use HodgePodge\Common;

class Collection extends Common\Collection
{
    public function __get($parameter)
    {
        $list = array();
        foreach($this->container as $item) {
            $value = $item->$parameter;
            if ($item instanceof Model) {
                if ($value instanceof Collection) {
                    $list = array_merge($list, $value->toArray());
                } else {
                    $list[] = $value;
                }
            } else {
                $list[] = $value;
            }
        }
        return new static($list);
    }

    public function __call($name, $arguments)
    {
        $list = array();
        foreach($this->container as $item) {
            if (!method_exists($item, $name)) {
                throw new \BadMethodCallException();
            }
            
            $value = call_user_func_array(array($item, $name),$arguments);
            if ($item instanceof Model) {
                if ($value instanceof Collection) {
                    $list = array_merge($list, $value->toArray());
                } else {
                    $list[] = $value;
                }
            } else {
                $list[] = $value;
            }
        }
        return new static($list);
    }

    public function __construct($array = null)
    {
        if (is_null($array)) $array = array();
        if ($array instanceof Collection) $array = $array->toArray();
        if (!is_array($array)) throw new \InvalidArgumentException('Orm\Collection::__construct() expects an array - ' . gettype($array) . ' given');
        
        $this->container = $array;
    }
    
    public function toArray($value = null, $key = 'id')
    {
        $return = array();
        
        // Empty array?
        if (!count($this->container)) return array();
        
        // If we are dealing with a collection of Model objects then user key/value to extract desired property
        if ($this->container[0] instanceof Model)
        {
            if(!$value) {
                foreach($this->container as $item) {
                    $return[$item->$key] = $item;
                }
                return $return;            
            }
            else
            {
                foreach($this->container as $item) {
                    $return[$item->$key] = $item->$value;
                }
                return $return;
            }
        }
        
        // If we have normal objects or primatives, just return the internal container
        return $this->container;
    }
    
    //////// Collection modifiers ////////
    public function unique()
    {
        $copy = $this->container;
        $clobberlist = [];
        
        foreach($copy as $key => $obj)
        {
            if (in_array($obj->id, $clobberlist))
            {
                unset($copy[$key]);
            }
            else
            {
                $clobberlist[] = $obj->id;
            }
        }
        
        return new static($copy);
    }
    
    public function sort($function)
    {
        $copy = $this->container;
        uasort($copy, $function);
        return new static($copy);
    }
    
    public function natSort($key = null)
    {
        if (!$key)
        {
            return $this->sort(function ($a, $b) {
                return strnatcmp((string) $a, (string) $b);
            });
        }
        else
        {
            return $this->sort(function ($a, $b) use ($key) {
                return strnatcmp($a->{$key}, $b->{$key});
            });            
        }
    }
{'fraction_non_alphanumeric': 0.13299823393560659, 'fraction_numerical': 0.0002717022143730471, 'mean_word_length': 1.3035043804755946, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 52, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6592340', 'n_tokens_mistral': 1963, 'n_tokens_neox': 1899, 'n_words': 461}