0

数据:

$players = array(
    new Player('psycketom'),
    new Player('stackexchanger'),
    new Player('max')
);

通常,为了从数组中的每个对象中获取一些东西,我们必须使用 /

foreach ($players as $player)
{
    var_dump( $player->score );
}

但是,由于这是一项重复性任务,有没有办法将其简化为沿着这些想象的线(?)

var_dump( every( $players )->score );

every( $players )->score += 40;

由于我没有看到的这种功能,有没有办法实现它?

我已经使用作为主要语言提出了这个问题,但是与代表问题的第二部分:哪些语言支持这种或至少类似的速记?

4

2 回答 2

2

所以,你是正确的,PHP 不支持这种“开箱即用”(除了有点,见下文)。我所知道的第一种语言是Objective-C(嗯,至少是CoreFoundation 库)。NSArrays 和其他集合具有(在一行中)指示应在所有成员上执行给定方法的方法;更酷(至少对我来说)是“keypaths”的概念以及NSArray和其他人对它们的支持。一个例子; 假设您有一组“人”,每个人都有一个父母,而他们又有一个“名字”:

arrayOfNames = [peopleArray valueForKeyPath:"parent.name"];

arrayOfNames 现在是所有父母姓名的数组。

PHP 最接近的东西是array_map,您可以将它与匿名函数一起使用以非常快速地将某些东西组合在一起。

尽管可能是轶事,但应该记住,如果只有一条语句要执行,则循环结构不需要花括号;所以任何更好的解决方案都需要与之竞争:

foreach($players as $p) $p->score += 40;

我会为那些 OOP 粉丝提到一个更深层次的解决方案......如果你使用集合对象而不是数组,那么世界就是你的牡蛎,拥有这样的东西。想到的最简单的概念就是php的魔术__call()方法。迭代您的成员并为您的用户发出调用有多简单?为了获得更多控制,您可以实施几种不同的迭代策略(一种用于转换,一种用于过滤器等。本质上,差异是返回的内容)。所以理论上你可以创建几个不同的迭代器类,并在你的“主”集合类中实现几个方法来获取其中一个,这些方法将使用以下内容进行预初始化:

$players->transform()->addScore(40);

其中 transform() 返回“不返回数组”迭代器的实例,该迭代器使用 __call() 技术。

此时天空开始打开,您可以开始构建过滤迭代器,它接受谓词并返回对象子集的另一个集合,这样的语法是可能的:

// send flyer to all parents with valid email address
$parentsPredicate = new Predicate('email');
$players->filteredByPredicate($parentsPredicate)->each()->email($fyler_email_body);
于 2012-08-31T06:58:01.660 回答
1

你可以这样做:

var_dump(array_map(function($el){return $el->score;}, $players));

array_walk($players, function($el) {$el->score += 40;});
于 2012-08-31T06:53:15.413 回答