PHPLinq
[ class tree: PHPLinq ] [ index: PHPLinq ] [ all elements ]

Source for file LinqToObjects.php

Documentation is available at LinqToObjects.php

  1. <?php
  2. /**
  3.  * PHPLinq
  4.  *
  5.  * Copyright (c) 2008 - 2009 PHPLinq
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  20.  *
  21.  * @category   PHPLinq
  22.  * @package    PHPLinq
  23.  * @copyright  Copyright (c) 2008 - 2009 PHPLinq (http://www.codeplex.com/PHPLinq)
  24.  * @license    http://www.gnu.org/licenses/lgpl.txt    LGPL
  25.  * @version    0.4.0, 2009-01-27
  26.  */
  27.  
  28.  
  29. /** PHPLinq */
  30. require_once('PHPLinq.php');
  31.  
  32. /** PHPLinq_ILinqProvider */
  33. require_once('PHPLinq/ILinqProvider.php');
  34.  
  35. /** PHPLinq_Expression */
  36. require_once('PHPLinq/Expression.php');
  37.  
  38. /** PHPLinq_OrderByExpression */
  39. require_once('PHPLinq/OrderByExpression.php');
  40.  
  41. /** PHPLinq_Initiator */
  42. require_once('PHPLinq/Initiator.php');
  43.  
  44. /** Register ILinqProvider */
  45. PHPLinq_Initiator::registerProvider('PHPLinq_LinqToObjects');
  46.  
  47.  
  48. /**
  49.  * PHPLinq_LinqToObjects
  50.  *
  51.  * @category   PHPLinq
  52.  * @package    PHPLinq
  53.  * @copyright  Copyright (c) 2008 - 2009 PHPLinq (http://www.codeplex.com/PHPLinq)
  54.  */
  55. class PHPLinq_LinqToObjects implements PHPLinq_ILinqProvider {
  56.     /**
  57.      * Default variable name
  58.      *
  59.      * @var string 
  60.      */
  61.     private $_from = '';
  62.     
  63.     /**
  64.      * Data source
  65.      *
  66.      * @var mixed 
  67.      */
  68.     private $_data = null;
  69.     
  70.     /**
  71.      * Where expression
  72.      *
  73.      * @var PHPLinq_Expression 
  74.      */
  75.     private $_where = null;
  76.     
  77.     /**
  78.      * Take n elements
  79.      *
  80.      * @var int? 
  81.      */
  82.     private $_take = null;
  83.     
  84.     /**
  85.      * Skip n elements
  86.      *
  87.      * @var int? 
  88.      */
  89.     private $_skip = null;
  90.     
  91.     /**
  92.      * Take while expression is true
  93.      *
  94.      * @var PHPLinq_Expression 
  95.      */
  96.     private $_takeWhile = null;
  97.     
  98.     /**
  99.      * Skip while expression is true
  100.      *
  101.      * @var PHPLinq_Expression 
  102.      */
  103.     private $_skipWhile = null;
  104.     
  105.     /**
  106.      * OrderBy expressions
  107.      *
  108.      * @var PHPLinq_Expression[] 
  109.      */
  110.     private $_orderBy = array();
  111.     
  112.     /**
  113.      * Distinct expression
  114.      *
  115.      * @var PHPLinq_Expression 
  116.      */
  117.     private $_distinct = null;
  118.     
  119.     /**
  120.      * OfType expression
  121.      *
  122.      * @var PHPLinq_Expression 
  123.      */
  124.     private $_ofType = null;
  125.     
  126.     /**
  127.      * Parent PHPLinq_ILinqProvider instance, used with join conditions
  128.      *
  129.      * @var PHPLinq_ILinqProvider 
  130.      */
  131.     private $_parentProvider = null;
  132.     
  133.     /**
  134.      * Child PHPLinq_ILinqProvider instances, used with join conditions
  135.      *
  136.      * @var PHPLinq_ILinqProvider[] 
  137.      */
  138.     private $_childProviders = array();
  139.     
  140.     /**
  141.      * Join condition
  142.      *
  143.      * @var PHPLinq_Expression 
  144.      */
  145.     private $_joinCondition = null;
  146.  
  147.     /**
  148.      * Is object destructing?
  149.      *
  150.      * @var bool 
  151.      */
  152.     private $_isDestructing;
  153.     
  154.     /**
  155.      * Can this provider type handle data in $source?
  156.      *
  157.      * @param mixed $source 
  158.      * @return bool 
  159.      */
  160.     public static function handles($source{
  161.         return is_array($source);
  162.     }
  163.     
  164.     /**
  165.      * Create a new class instance
  166.      *
  167.      * @param string $name 
  168.      * @param PHPLinq_ILinqProvider $parentProvider Optional parent PHPLinq_ILinqProvider instance, used with join conditions
  169.      * @return PHPLinq_ILinqProvider 
  170.      */
  171.     public function __construct($namePHPLinq_ILinqProvider $parentProvider null{
  172.         $this->_from = $name;
  173.         
  174.         if (!is_null($parentProvider)) {
  175.             $this->_parentProvider = $parentProvider;
  176.             $parentProvider->addChildProvider($this);
  177.         }
  178.         
  179.         return $this;
  180.     }
  181.     
  182.     /**
  183.      * Class destructor
  184.      */
  185.     public function __destruct({
  186.         $this->_isDestructing = true;
  187.  
  188.         if (isset($this->_parentProvider&& !is_null($this->_parentProvider)) {
  189.             if (!$this->_parentProvider->__isDestructing()) {
  190.                 $this->_parentProvider->__destruct();
  191.             }
  192.             $this->_parentProvider = null;
  193.             unset($this->_parentProvider);
  194.         }
  195.         
  196.         if (!is_null($this->_childProviders)) {
  197.             foreach ($this->_childProviders as $provider{
  198.                 $provider->__destruct();
  199.                 $provider null;
  200.                 unset($provider);
  201.             }
  202.         }
  203.     }
  204.  
  205.     /**
  206.      * Is object destructing?
  207.      *
  208.      * @return bool 
  209.      */
  210.     public function __isDestructing({
  211.         return $this->_isDestructing;
  212.     }
  213.     
  214.     /**
  215.      * Get join condition
  216.      *
  217.      * @return PHPLinq_Expression 
  218.      */
  219.     public function getJoinCondition({
  220.         return $this->_joinCondition;
  221.     }
  222.     
  223.     /**
  224.      * Add child provider, used with joins
  225.      *
  226.      * @param PHPLinq_ILinqProvider $provider 
  227.      */
  228.     public function addChildProvider(PHPLinq_ILinqProvider $provider{
  229.         $this->_childProviders[$provider;
  230.     }
  231.     
  232.     /**
  233.      * Retrieve "from" name
  234.      *
  235.      * @return string 
  236.      */
  237.     public function getFromName({
  238.         return $this->_from;
  239.     }
  240.     
  241.     /**
  242.      * Retrieve data in data source
  243.      *
  244.      * @return mixed 
  245.      */
  246.     public function getSource({
  247.         return $this->_data;
  248.     }
  249.     
  250.     /**
  251.      * Set source of data
  252.      *
  253.      * @param mixed $source 
  254.      * @return PHPLinq_ILinqProvider 
  255.      */
  256.     public function in($source{
  257.         $this->_data = $source;
  258.         return $this;
  259.     }
  260.     
  261.     /**
  262.      * Select
  263.      *
  264.      * @param  string    $expression    Expression which creates a resulting element
  265.      * @return mixed 
  266.      */
  267.     public function select($expression null{
  268.         // Returnvalue
  269.         $returnValue array();
  270.             
  271.         // Expression set?
  272.         if (is_null($expression|| $expression == ''{
  273.             $expression $this->_from . ' => ' $this->_from;
  274.         }
  275.  
  276.         // OrderBy set?
  277.         if (is_array($this->_orderBy&& count($this->_orderBy0{
  278.             // Create sorter
  279.             $sorter '';
  280.             
  281.             // Is there only one OrderBy expression?
  282.             if (count($this->_orderBy== 1{
  283.                 // First sorter
  284.                 $sorter $this->_orderBy[0]->getFunctionReference();
  285.             else {
  286.                 // Create OrderBy expression
  287.                 $compareCode '';
  288.                 
  289.                 // Compile comparer function
  290.                 $compareCode "
  291.                     \$result = null;
  292.                 ";
  293.                 for ($i 0$i count($this->_orderBy)$i++{
  294.                     
  295.                     $f substr($this->_orderBy[$i]->getFunctionReference()1)
  296.                     $compareCode .= "
  297.                     \$result = call_user_func_array(chr(0).'$f', array({$this->_from}A, {$this->_from}B));
  298.                     if (\$result != 0) {
  299.                         return \$result;
  300.                     }
  301.                     ";
  302.                     
  303.                 }
  304.                 $compareCode .= "return \$result;";
  305.                 $sorter = create_function($this->_from . 'A, ' $this->_from . 'B'$compareCode);
  306.             }
  307.             
  308.             // Sort!
  309.             usort($this->_data$sorter);
  310.         }
  311.         
  312.         // Data source
  313.         $dataSource = array();
  314.         
  315.         // Build possible join data
  316.         foreach ($this->_data as $value) {
  317.             // Child providers set?
  318.             if (count($this->_childProviders) > 0) {
  319.                 // Data to be joined
  320.                 $joinedData = array();
  321.                 $joinedData[$this->_from][] = $value;
  322.                         
  323.                 // Join other values
  324.                 foreach ($this->_childProviders as $provider) {
  325.                     // Fetch possible join data
  326.                     foreach ($provider->select() as $record) {
  327.                         $joinValid = $provider->getJoinCondition()->execute( array( $this->_from => $value, $provider->getFromName() => $record ) );
  328.                         if ($joinValid) {
  329.                             $joinedData[$provider->getFromName()][] = $record;
  330.                         }
  331.                     }
  332.                 }
  333.  
  334.                 /** BEGIN CARTESIAN JOIN */
  335.                 
  336.                 // Joinable array
  337.                 $joinable = array();
  338.                         
  339.                 // Join data keys
  340.                 $joinedDataKeys = array_keys($joinedData);
  341.                         
  342.                 // Calculate expected size of $joinable
  343.                 $size = (count($joinedData) > 0 ? 1 : 0);
  344.                 foreach ($joinedData as $values) {
  345.                     $size = $size * count($values);
  346.                 }
  347.                 
  348.                 // Create cartesian array
  349.                 for ($i = 0; $i < $size; $i++) {
  350.                     $joinable[$i] = array();
  351.                     
  352.                     for ($j = 0; $j < count($joinedData); $j++) {
  353.                         array_push($joinable[$i], current($joinedData[$joinedDataKeys[$j]]));
  354.                     }
  355.                     
  356.                     // Set cursor on next element in the $joinedData, beginning with the last array
  357.                     for ($j = (count($joinedData)-1); $j >= 0; $j--) {
  358.                         // If next returns true, then break
  359.                         if (next($joinedData[$joinedDataKeys[$j]])) {
  360.                             break;
  361.                         } else {
  362.                             // If next returns false, then reset and go on with previous $joinedData...
  363.                             reset($joinedData[$joinedDataKeys[$j]]);
  364.                         }
  365.                     }
  366.                 }
  367.                 
  368.                 /** END CARTESIAN JOIN */
  369.                         
  370.                 // Join values using selector expression
  371.                 foreach ($joinable as $values) {
  372.                     $dataSource[] = $values;
  373.                 }
  374.             }
  375.         }
  376.         
  377.         // Data source filled?
  378.         if (count($dataSource) == 0) {
  379.             $dataSource = $this->_data;
  380.         }
  381.  
  382.         // Distinct values storage
  383.         $distinctValues = array();
  384.         
  385.         // Create selector expression
  386.         $selector = new PHPLinq_Expression($expression, $this->_from);
  387.         
  388.         // Count elements
  389.         $elementCount = 0;
  390.         
  391.         // Loop trough data source
  392.         foreach ($dataSource as $value) {
  393.             // Is it a valid element?
  394.             $isValid = true;
  395.             
  396.             // OfType expresion set? Evaluate it!
  397.             if ($isValid && !is_null($this->_ofType)) {
  398.                 $isValid = $this->_ofType->execute($value);
  399.             }
  400.             
  401.             // Where expresion set? Evaluate it!
  402.             if ($isValid && !is_null($this->_where)) {
  403.                 $isValid = $this->_where->execute($value);
  404.             }
  405.             
  406.             // Distinct expression set? Evaluate it!
  407.             if ($isValid && !is_null($this->_distinct)) {
  408.                 $distinctKey = $this->_distinct->execute($value);
  409.                 if (isset($distinctValues[$distinctKey])) {
  410.                     $isValid = false;
  411.                 } else {
  412.                     $distinctValues[$distinctKey] = 1; 
  413.                 }
  414.             }
  415.             
  416.             // The element is valid, check if it is our selection range
  417.             if ($isValid) {
  418.                     
  419.                 // Skip element?
  420.                 if (!is_null($this->_skipWhile) && $this->_skipWhile->execute($value)) {
  421.                     $isValid = false;
  422.                 }
  423.                 if (!is_null($this->_skip) && $elementCount < $this->_skip) {
  424.                     $isValid = false;
  425.                 }
  426.                 
  427.                 // Take element?
  428.                 if (!is_null($this->_takeWhile) && !$this->_takeWhile->execute($value)) {
  429.                     $isValid = false;
  430.                     break;
  431.                 }
  432.                 if (!is_null($this->_take) && count($returnValue) >= $this->_take) {
  433.                     $isValid = false;
  434.                     break;
  435.                 }
  436.  
  437.                 // Next element
  438.                 $elementCount++;
  439.  
  440.                 // Add the element to the return value if it is a valid element
  441.                 if ($isValid) {
  442.                     $returnValue[] = $selector->execute($value);
  443.                 }
  444.             }
  445.         }
  446.         
  447.         // Return value
  448.         return $returnValue;
  449.     }
  450.     
  451.     /**
  452.      * Where
  453.      *
  454.      * @param  string    $expression    Expression checking if an element should be contained
  455.      * @return PHPLinq_ILinqProvider
  456.      */
  457.     public function where($expression) {
  458.         $this->_where = !is_null($expression) ? new PHPLinq_Expression($expression, $this->_from) : null;
  459.         return $this;
  460.     }
  461.     
  462.     /**
  463.      * Take $n elements
  464.      *
  465.      * @param int $n
  466.      * @return PHPLinq_ILinqProvider
  467.      */
  468.     public function take($n) {
  469.         $this->_take = $n;
  470.         return $this;
  471.     }
  472.     
  473.     /**
  474.      * Skip $n elements
  475.      *
  476.      * @param int $n
  477.      * @return PHPLinq_ILinqProvider
  478.      */
  479.     public function skip($n) {
  480.         $this->_skip = $n;
  481.         return $this;
  482.     }
  483.     
  484.     /**
  485.      * Take elements while $expression evaluates to true
  486.      *
  487.      * @param  string    $expression    Expression to evaluate
  488.      * @return PHPLinq_ILinqProvider
  489.      */
  490.     public function takeWhile($expression) {
  491.         $this->_takeWhile = !is_null($expression) ? new PHPLinq_Expression($expression, $this->_from) : null;
  492.         return $this;
  493.     }
  494.     
  495.     /**
  496.      * Skip elements while $expression evaluates to true
  497.      *
  498.      * @param  string    $expression    Expression to evaluate
  499.      * @return PHPLinq_ILinqProvider
  500.      */
  501.     public function skipWhile($expression) {
  502.         $this->_skipWhile = !is_null($expression) ? new PHPLinq_Expression($expression, $this->_from) : null;
  503.         return $this;
  504.     }
  505.     
  506.     /**
  507.      * OrderBy
  508.      *
  509.      * @param  string    $expression    Expression to order elements by
  510.      * @param  string    $comparer    Comparer function (taking 2 arguments, returning -1, 0, 1)
  511.      * @return PHPLinq_ILinqProvider
  512.      */
  513.     public function orderBy($expression, $comparer = null) {
  514.         $this->_orderBy[0] = new PHPLinq_OrderByExpression($expression, $this->_from, false, $comparer);
  515.         return $this;
  516.     }
  517.     
  518.     /**
  519.      * OrderByDescending
  520.      *
  521.      * @param  string    $expression    Expression to order elements by
  522.      * @param  string    $comparer    Comparer function (taking 2 arguments, returning -1, 0, 1)
  523.      * @return PHPLinq_ILinqProvider
  524.      */
  525.     public function orderByDescending($expression, $comparer = null) {
  526.         $this->_orderBy[0] = new PHPLinq_OrderByExpression($expression, $this->_from, true, $comparer);
  527.         return $this;
  528.     }
  529.     
  530.     /**
  531.      * ThenBy
  532.      *
  533.      * @param  string    $expression    Expression to order elements by
  534.      * @param  string    $comparer    Comparer function (taking 2 arguments, returning -1, 0, 1)
  535.      * @return PHPLinq_ILinqProvider
  536.      */
  537.     public function thenBy($expression, $comparer = null) {
  538.         $this->_orderBy[] = new PHPLinq_OrderByExpression($expression, $this->_from, false, $comparer);
  539.         return $this;
  540.     }
  541.     
  542.     /**
  543.      * ThenByDescending
  544.      *
  545.      * @param  string    $expression    Expression to order elements by
  546.      * @param  string    $comparer    Comparer function (taking 2 arguments, returning -1, 0, 1)
  547.      * @return PHPLinq_ILinqProvider
  548.      */
  549.     public function thenByDescending($expression, $comparer = null) {
  550.         $this->_orderBy[] = new PHPLinq_OrderByExpression($expression, $this->_from, true, $comparer);
  551.         return $this;
  552.     }
  553.     
  554.     /**
  555.      * Distinct
  556.      *
  557.      * @param  string    $expression    Expression to retrieve the key value. 
  558.      * @return PHPLinq_ILinqProvider
  559.      */
  560.     public function distinct($expression) {
  561.         $this->_distinct = !is_null($expression) ? new PHPLinq_Expression($expression, $this->_from) : null;
  562.         return $this;
  563.     }
  564.     
  565.     /**
  566.      * Select the elements of a certain type
  567.      *
  568.      * @param string $type    Type name
  569.      */
  570.     public function ofType($type) {
  571.         // Create a new expression
  572.         $expression = $this->_from . ' => ';
  573.         
  574.         // Evaluate type
  575.         switch (strtolower($type)) {
  576.             case 'array':
  577.             case 'bool':
  578.             case 'double':
  579.             case 'float':
  580.             case 'int':
  581.             case 'integer':
  582.             case 'long':
  583.             case 'null':
  584.             case 'numeric':
  585.             case 'object':
  586.             case 'real':
  587.             case 'scalar':
  588.             case 'string':
  589.                 $expression .= 'is_' . strtolower($type) . '(' . $this->_from . ')';
  590.                 break;
  591.             default:
  592.                 $expression .= 'is_a(' . $this->_from . ', "' . $type . '")';
  593.                 break;
  594.         }
  595.         
  596.         // Assign expression
  597.         $this->_ofType = new <a href="../PHPLinq/PHPLinq_Expression.html">PHPLinq_Expression</a>($expression, $this->_from);
  598.         return $this;
  599.     }
  600.     
  601.     /**
  602.      * Any
  603.      *
  604.      * @param  string    $expression    Expression checking if an element is contained
  605.      * @return boolean
  606.      */
  607.     public function any($expression) {
  608.         $originalWhere = $this->_where;
  609.         
  610.         $result = $this->where($expression)->select($this->_from);
  611.         
  612.         $this->_where = $originalWhere;
  613.         
  614.         return count($result) > 0;
  615.     }
  616.     
  617.     /**
  618.      * All
  619.      *
  620.      * @param  string    $expression    Expression checking if an all elements are contained
  621.      * @return boolean
  622.      */
  623.     public function all($expression) {
  624.         $originalWhere = $this->_where;
  625.         
  626.         $result = $this->where($expression)->select($this->_from);
  627.         
  628.         $this->_where = $originalWhere;
  629.         
  630.         return count($result) == count($this->_data);
  631.     }
  632.  
  633.     /**
  634.      * Contains
  635.      *
  636.      * @param mixed $element Is the $element contained?
  637.      * @return boolean
  638.      */
  639.     public function contains($element) {
  640.         return in_array($element, $this->_data);
  641.     }
  642.     
  643.     /**
  644.      * Reverse elements
  645.      * 
  646.      * @param bool $preserveKeys Preserve keys?
  647.      * @return PHPLinq_ILinqProvider
  648.      */
  649.     public function reverse($preserveKeys = null) {
  650.         $data = array_reverse($this->select(), $preserveKeys);
  651.         return linqfrom($this->_from)->in($data);
  652.     }
  653.     
  654.     /**
  655.      * Element at index
  656.      *
  657.      * @param mixed $index Index
  658.      * @return mixed Element at $index
  659.      */
  660.     public function elementAt($index = null) {
  661.         $originalWhere = $this->_where;
  662.         
  663.         $result = isset($this->_data[$index]) ? $this->_data[$index] : null;
  664.         
  665.         $this->_where = $originalWhere;
  666.         
  667.         if (count($result) > 0) {
  668.             return array_shift($result);
  669.         }
  670.         return null;
  671.     }
  672.     
  673.     /**
  674.      * Element at index or default
  675.      *
  676.      * @param mixed $index Index
  677.      * @param  mixed $defaultValue Default value to return if nothing is found
  678.      * @return mixed Element at $index
  679.      */
  680.     public function elementAtOrDefault($index = null, $defaultValue = null) {
  681.         $returnValue = $this->elementAt($index);
  682.         if (!is_null($returnValue)) {
  683.             return $returnValue;
  684.         } else {
  685.             return $defaultValue;
  686.         }
  687.     }
  688.     
  689.     /**
  690.      * Concatenate data
  691.      *
  692.      * @param mixed $source
  693.      * @return PHPLinq_ILinqProvider
  694.      */
  695.     public function concat($source) {
  696.         $data = array_merge($this->select(), $source);
  697.         return linqfrom($this->_from)->in($data);
  698.     }
  699.     
  700.     /**
  701.      * First
  702.      *
  703.      * @param  string    $expression    Expression which creates a resulting element
  704.      * @return mixed
  705.      */
  706.     public function first($expression = null) {
  707.         $linqCommand = clone $this;
  708.         $result = $linqCommand->skip(0)->take(1)->select($expression);
  709.         if (count($result) > 0) {
  710.             return array_shift($result);
  711.         }
  712.         return null;
  713.     }
  714.     
  715.     /**
  716.      * FirstOrDefault 
  717.      *
  718.      * @param  string    $expression    Expression which creates a resulting element
  719.      * @param  mixed    $defaultValue Default value to return if nothing is found
  720.      * @return mixed
  721.      */
  722.     public function firstOrDefault ($expression = null, $defaultValue = null) {
  723.         $returnValue = $this->first($expression);
  724.         if (!is_null($returnValue)) {
  725.             return $returnValue;
  726.         } else {
  727.             return $defaultValue;
  728.         }
  729.     }
  730.     
  731.     /**
  732.      * Last
  733.      *
  734.      * @param  string    $expression    Expression which creates a resulting element
  735.      * @return mixed
  736.      */
  737.     public function last($expression = null) {
  738.         $linqCommand = clone $this;
  739.         $result = $linqCommand->reverse()->skip(0)->take(1)->select($expression);
  740.         if (count($result) > 0) {
  741.             return array_shift($result);
  742.         }
  743.         return null;
  744.     }
  745.     
  746.     /**
  747.      * LastOrDefault 
  748.      *
  749.      * @param  string    $expression    Expression which creates a resulting element
  750.      * @param  mixed    $defaultValue Default value to return if nothing is found
  751.      * @return mixed
  752.      */
  753.     public function lastOrDefault ($expression = null, $defaultValue = null) {
  754.         $returnValue = $this->last($expression);
  755.         if (!is_null($returnValue)) {
  756.             return $returnValue;
  757.         } else {
  758.             return $defaultValue;
  759.         }
  760.     }
  761.     
  762.     /**
  763.      * Single
  764.      *
  765.      * @param  string    $expression    Expression which creates a resulting element
  766.      * @return mixed
  767.      */
  768.     public function single($expression = null) {
  769.         return $this->first($expression);
  770.     }
  771.     
  772.     /**
  773.      * SingleOrDefault 
  774.      *
  775.      * @param  string    $expression    Expression which creates a resulting element
  776.      * @param  mixed    $defaultValue Default value to return if nothing is found
  777.      * @return mixed
  778.      */
  779.     public function singleOrDefault ($expression = null, $defaultValue = null) {
  780.         return $this->firstOrDefault($expression, $defaultValue);
  781.     }
  782.     
  783.     /**
  784.      * Join
  785.      *
  786.      * @param string $name
  787.      * @return PHPLinq_Initiator
  788.      */
  789.     public function join($name) {
  790.         return new <a href="../PHPLinq/PHPLinq_Initiator.html">PHPLinq_Initiator</a>($name, $this);
  791.     }
  792.     
  793.     /**
  794.      * On
  795.      *
  796.      * @param  string    $expression    Expression representing join condition
  797.      * @return PHPLinq_ILinqProvider
  798.      */
  799.     public function on($expression) {
  800.         $this->_joinCondition = new <a href="../PHPLinq/PHPLinq_Expression.html">PHPLinq_Expression</a>($expression, $this->_from);
  801.         return $this->_parentProvider;
  802.     }
  803.     
  804.     /**
  805.      * Count elements
  806.      *
  807.      * @return int Element count
  808.      */
  809.     public function count() {
  810.         return count($this->_data);
  811.     }
  812.     
  813.     /**
  814.      * Sum elements
  815.      *
  816.      * @return mixed Sum of elements
  817.      */
  818.     public function sum() {
  819.         return array_sum($this->_data); // $this->aggregate(0, '$s, $t => $s + $t');
  820.     }
  821.     
  822.     /**
  823.      * Minimum of elements
  824.      *
  825.      * @return mixed Minimum of elements
  826.      */
  827.     public function min(){
  828.         return min($this->_data);
  829.     }
  830.     
  831.     /**
  832.      * Maximum of elements
  833.      *
  834.      * @return mixed Maximum of elements
  835.      */
  836.     public function max(){
  837.         return max($this->_data);
  838.     }
  839.     
  840.     /**
  841.      * Average of elements
  842.      *
  843.      * @return mixed Average of elements
  844.      */
  845.     public function average(){
  846.         return $this->sum() / $this->count();
  847.     }
  848.  
  849.     /**
  850.      * Aggregate
  851.      * 
  852.      * Example: Equivalent of count(): $this->aggregate(0, '$s, $t => $s + 1');
  853.      *
  854.      * @param int $seed    Seed
  855.      * @param string $expression    Expression defining the aggregate
  856.      * @return mixed aggregate
  857.      */
  858.     public function aggregate($seed = 0, $expression) {
  859.         $codeExpression = new <a href="../PHPLinq/PHPLinq_Expression.html">PHPLinq_Expression</a>($expression);
  860.         
  861.         $runningValue = $seed;
  862.         foreach ($this->_data as $value) {
  863.             $runningValue = $codeExpression->execute( array($runningValue, $value) );
  864.         }
  865.         
  866.         return $runningValue;
  867.     }

Documentation generated on Tue, 27 Jan 2009 08:29:27 +0100 by phpDocumentor 1.4.1