Skip to content
This repository has been archived by the owner on Oct 18, 2023. It is now read-only.

Commit

Permalink
add easy expressions for where(), whereFirst(), whereFirstOrDefault()
Browse files Browse the repository at this point in the history
  • Loading branch information
perryflynn committed Sep 25, 2017
1 parent 268178c commit c682859
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 28 deletions.
49 changes: 27 additions & 22 deletions src/PerrysLambda/ArrayBase.php
Expand Up @@ -552,8 +552,8 @@ public function removeKey($field)
if($this->exists($field))
{
unset($this->__data[$field]);
$this->invalidateKeycache();
}
$this->invalidateKeycache();
return $this;
}

Expand Down Expand Up @@ -612,11 +612,12 @@ abstract public function getIsValidValue($value);

/**
* filter by condition
* @param callable $where
* @param callable|array $where
* @return \PerrysLambda\ArrayList
*/
public function where(callable $where)
public function where($where)
{
$where = LambdaUtils::toConditionCallable($where);
$collection = $this->newInstance();
foreach($this as $record)
{
Expand All @@ -630,12 +631,13 @@ public function where(callable $where)

/**
* Get first item matching to callable
* @param callable $where
* @param callable|array $where
* @return mixed
* @throws \OutOfBoundsException
*/
public function whereFirst(callable $where)
public function whereFirst($where)
{
$where = LambdaUtils::toConditionCallable($where);
foreach($this as $record)
{
if(call_user_func($where, $record))
Expand All @@ -648,12 +650,13 @@ public function whereFirst(callable $where)

/**
* Get first item matching to callable or default
* @param callable $where
* @param callable|array $where
* @param mixed $default
* @return mixed
*/
public function whereFirstOrDefault(callable $where, $default=null)
public function whereFirstOrDefault($where, $default=null)
{
$where = LambdaUtils::toConditionCallable($where);
foreach($this as $record)
{
if(call_user_func($where, $record))
Expand All @@ -671,7 +674,7 @@ public function whereFirstOrDefault(callable $where, $default=null)
*/
public function groupBy($group=null)
{
$group = LambdaUtils::toCallable($group);
$group = LambdaUtils::toSelectCallable($group);

$result = new ObjectArray(array());
if($this instanceof ObjectArray)
Expand Down Expand Up @@ -703,7 +706,7 @@ public function groupBy($group=null)
*/
public function distinct($distinct=null)
{
$distinct = LambdaUtils::toCallable($distinct);
$distinct = LambdaUtils::toSelectCallable($distinct);

$keys = array();
$collection = $this->newInstance();
Expand Down Expand Up @@ -759,11 +762,12 @@ public function except(ArrayBase $comparedata)

/**
* Check for any field by condition
* @param callable $where
* @param callable|array $where
* @return bool
*/
public function any(callable $where)
public function any($where)
{
$where = LambdaUtils::toConditionCallable($where);
foreach($this as $record)
{
if(call_user_func($where, $record))
Expand All @@ -776,11 +780,12 @@ public function any(callable $where)

/**
* Check for all fields by condition
* @param callable $where
* @param callable|array $where
* @return bool
*/
public function all(callable $where)
public function all($where)
{
$where = LambdaUtils::toConditionCallable($where);
foreach($this as $record)
{
if(!call_user_func($where, $record))
Expand All @@ -798,7 +803,7 @@ public function all(callable $where)
*/
public function select($select=null)
{
$select = LambdaUtils::toCallable($select);
$select = LambdaUtils::toSelectCallable($select);

$result = array();
foreach($this as $key => $record)
Expand All @@ -815,7 +820,7 @@ public function select($select=null)
*/
public function selectMany($select=null)
{
$select = LambdaUtils::toCallable($select);
$select = LambdaUtils::toSelectCallable($select);

$result = array();
foreach($this as $key => $record)
Expand Down Expand Up @@ -858,7 +863,7 @@ public function each(callable $each)
*/
public function sum($sum=null)
{
$sum = LambdaUtils::toCallable($sum);
$sum = LambdaUtils::toSelectCallable($sum);
$temp = $this->select($sum)->toArray();
return array_sum($temp);
}
Expand All @@ -870,7 +875,7 @@ public function sum($sum=null)
*/
public function min($min=null)
{
$min = LambdaUtils::toCallable($min);
$min = LambdaUtils::toSelectCallable($min);
$temp = $this->select($min)->toArray();
return min($temp);
}
Expand All @@ -882,7 +887,7 @@ public function min($min=null)
*/
public function max($max=null)
{
$max = LambdaUtils::toCallable($max);
$max = LambdaUtils::toSelectCallable($max);
$temp = $this->select($max)->toArray();
return max($temp);
}
Expand All @@ -894,7 +899,7 @@ public function max($max=null)
*/
public function avg($avg=null)
{
$avg = LambdaUtils::toCallable($avg);
$avg = LambdaUtils::toSelectCallable($avg);
return ($this->sum($avg)/$this->length());
}

Expand All @@ -906,7 +911,7 @@ public function avg($avg=null)
*/
public function joinString($join=null, $glue=", ")
{
$join = LambdaUtils::toCallable($join);
$join = LambdaUtils::toSelectCallable($join);
$temp = $this->select($join)->toArray();
return implode($glue, $temp);
}
Expand Down Expand Up @@ -1061,7 +1066,7 @@ public function skip($offset)
*/
public function order($order)
{
$order = LambdaUtils::toCallable($order);
$order = LambdaUtils::toSelectCallable($order);
return Sortable::startOrder($this, $order);
}

Expand All @@ -1072,7 +1077,7 @@ public function order($order)
*/
public function orderDesc($order)
{
$order = LambdaUtils::toCallable($order);
$order = LambdaUtils::toSelectCallable($order);
return Sortable::startOrderDesc($this, $order);
}

Expand Down
50 changes: 49 additions & 1 deletion src/PerrysLambda/LambdaUtils.php
Expand Up @@ -14,7 +14,7 @@ class LambdaUtils
* @return callable
* @throws \PerrysLambda\Exception\InvalidException
*/
public static function toCallable($mixed=null)
public static function toSelectCallable($mixed=null)
{
// callable
if(is_callable($mixed))
Expand Down Expand Up @@ -48,5 +48,53 @@ public static function toCallable($mixed=null)

throw new InvalidException("Could not convert expression of type ".gettype($mixed)." into a lambda callable");
}


/**
* Convert strings, numbers, booleans and arrays into a callable
* @param type $mixed
* @return type
* @throws InvalidException
*/
public static function toConditionCallable($mixed=null)
{
// callable
if(is_callable($mixed))
{
return $mixed;
}
// is bool
elseif(is_bool($mixed) || is_string($mixed) || is_numeric($mixed))
{
return function($v) use($mixed) { return $v===$mixed; };
}
// conditions from array
elseif(is_array($mixed) && count($mixed)>0)
{
return function($v) use($mixed)
{
foreach($mixed as $field => $expression)
{
if(is_callable($expression))
{
if($expression($v[$field])!==true)
{
return false;
}
}
else
{
if($v[$field]!==$expression)
{
return false;
}
}
}
return true;
};
}

throw new InvalidException("Could not convert expression of type ".gettype($mixed)." into a lambda callable");
}

}
8 changes: 4 additions & 4 deletions src/PerrysLambda/Sortable.php
Expand Up @@ -20,7 +20,7 @@ class Sortable
*/
public static function startOrder(ArrayList $list, $order)
{
$order = LambdaUtils::toCallable($order);
$order = LambdaUtils::toSelectCallable($order);
$temp = new static($list, $order, self::ORDER_ASC);
$temp->thenBy($order);
return $temp;
Expand All @@ -34,7 +34,7 @@ public static function startOrder(ArrayList $list, $order)
*/
public static function startOrderDesc(ArrayList $list, $order)
{
$order = LambdaUtils::toCallable($order);
$order = LambdaUtils::toSelectCallable($order);
$temp = new static($list, $order, self::ORDER_DESC);
$temp->thenByDesc($order);
return $temp;
Expand All @@ -54,7 +54,7 @@ protected function __construct(ArrayList $list)
*/
public function thenBy($order)
{
$order = LambdaUtils::toCallable($order);
$order = LambdaUtils::toSelectCallable($order);
$this->orders[] = array("property" => $order, "direction" => self::ORDER_ASC);
return $this;
}
Expand All @@ -66,7 +66,7 @@ public function thenBy($order)
*/
public function thenByDesc($order)
{
$order = LambdaUtils::toCallable($order);
$order = LambdaUtils::toSelectCallable($order);
$this->orders[] = array("property" => $order, "direction" => self::ORDER_DESC);
return $this;
}
Expand Down
2 changes: 1 addition & 1 deletion test/ExceptionTest.php
Expand Up @@ -114,7 +114,7 @@ public function testSkipOutOfBounds()
*/
public function testCallableBoolean()
{
\PerrysLambda\LambdaUtils::toCallable(true);
\PerrysLambda\LambdaUtils::toSelectCallable(true);
}

/**
Expand Down
10 changes: 10 additions & 0 deletions test/LambdaTest.php
Expand Up @@ -185,10 +185,15 @@ public function testLambda()

// any / all
$this->assertSame(true, $basic->any(function($v) { return $v===1; }));
$this->assertSame(true, $basic->any(1));
$this->assertSame(false, $basic->all(function($v) { return $v===1; }));
$this->assertSame(false, $basic->all(1));
$this->assertSame(true, $all->all(function($v) { return $v===1; }));
$this->assertSame(true, $all->all(1));
$this->assertSame(true, $all->any(function($v) { return $v===1; }));
$this->assertSame(true, $all->any(1));
$this->assertSame(false, $all->any(function($v) { return $v===2; }));
$this->assertSame(false, $all->any(2));

// wherefirst
$this->assertSame(5, $basic->whereFirst(function($v) { return $v>4; }));
Expand Down Expand Up @@ -248,6 +253,11 @@ public function testLambdaByString()
);

$list = ArrayList::asObjectArray($testdata);

$this->assertSame(3, $list->where(array('b'=>'bar'))->first()->a);
$this->assertSame(3, $list->whereFirst(array('b'=>'bar'))->a);
$this->assertSame(3, $list->whereFirstOrDefault(array('b'=>'bar'))->a);
$this->assertSame(null, $list->whereFirstOrDefault(array('b'=>'asdf')));

$this->assertSame(14, $list->sum('a'));
$this->assertSame(2, $list->min('a'));
Expand Down

0 comments on commit c682859

Please sign in to comment.