我正在创建一个数组类,希望一个值能够被高阶函数返回。这个想法是它的实例常量或方法返回值,这样我就可以跳过map
中的值。
在其他语言中,创建数组或某个复合值(例如['skip']
)将使其等于指针,这样我就可以使用运算符将其等于指针,并且它将不等于具有相同内容的其他数组,但是我的问题是['skip'] === ['skip']
是正确的,因此即使使用===
,两个值也相同。
这是我的代码用法示例,其中我具有与过去跳过相同的值:
namespace Test;
use Common\Domain\Collection;
$arr = new Collection();
$arr[] = 1;
$arr[] = 2;
$arr[] = 3;
$arr[] = 4;
echo count($arr); // prints 4
$arr2 = $arr->map(function ($v) {
return $v % 2 == 0 ? Collection::SKIP : ["skip"];
});
echo count($arr2); // prints 0, but should be 2
是否有办法获得独特的价值或以某种方式解决?
这是实现Collection
的代码:
namespace Common\Domain;;
class Collection implements \Iterator, \Countable, \ArrayAccess
{
const SKIP = ["skip"];
private $arr = [];
public function map(callable $fn, bool $keepKeys = false) :Collection
{
$arr = new static();
$nOrder = 0;
foreach($this->arr as $key => $value) {
$result = call_user_func($fn, $value, $key, $nOrder, $this);
if($result !== self::SKIP) {
if($keepKeys) {
$arr[$key] = $result;
} else {
$arr[] = $result;
}
}
}
return $arr;
}
// implementation of interfaces \Iterator, \Countable, \ArrayAccess
public function current()
{
return current($this->arr);
}
public function next()
{
next($this->arr);
}
public function key()
{
return key($this->arr);
}
public function valid()
{
return isset($this->arr[$this->key()]);
}
public function rewind()
{
reset($this->arr);
}
public function count()
{
return count($this->arr);
}
public function offsetExists($offset)
{
return array_key_exists($offset, $this->arr);
}
public function offsetGet($offset)
{
return $this->arr[$offset];
}
public function offsetSet($offset, $value)
{
$this->arr[$offset] = $value;
}
public function offsetUnset($offset)
{
unset($this->arr[$offset]);
}
}
答案 0 :(得分:1)
我猜您正在寻找Java类型的枚举,PHP中不存在。我对您的问题的最佳猜测是使用一个对象而不是一个常量,您可以将其静态实例化以方便使用。然后,在map函数的循环中,使用instanceof
而不是基本的相等运算符,根据定义的类检查值。
所以,这里:
class UniqueValue
{
public static function get()
{
return new self();
}
}
然后:
$arr2 = $arr->map(function ($v) {
return $v % 2 == 0 ? UniqueValue::get() : ["skip"];
});
在您的收藏夹中:
public function map(callable $fn, bool $keepKeys = false) :Collection
{
$arr = new static();
$nOrder = 0;
foreach($this->arr as $key => $value) {
$result = call_user_func($fn, $value, $key, $nOrder, $this);
if($result ! instanceof UniqueValue) {
if($keepKeys) {
$arr[$key] = $result;
} else {
$arr[] = $result;
}
}
}
return $arr;
}
这是我能想到的最快的方法。如果您的数组包含“外部”数据,则我认为它不可能与您自己代码中的类检查相匹配。
答案 1 :(得分:0)
我将通过为此实现另一种方法来解决此问题。方法delete
将一个函数映射到集合上,并删除该函数返回false的所有元素。
例如
class Collection
{
// ...
public function delete($func)
{
$result = new static();
foreach($this->arr as $item)
{
if($func($item) !== false) $result[] = $item;
}
}
}
// example
$arr = new Collection();
$arr[] = 1;
$arr[] = 2;
$arr[] = 3;
$arr[] = 4;
echo count($arr); // prints 4
$arr2 = $arr->delete(function ($v) {
return $v % 2 ? true : false;
});
var_dump($arr2); // prints [2, 4]