数据:
$players = array(
new Player('psycketom'),
new Player('stackexchanger'),
new Player('max')
);
通常,为了从数组中的每个对象中获取内容,我们必须使用for / foreach。
foreach ($players as $player)
{
var_dump( $player->score );
}
但是,既然这是一个重复性的任务,那么是否有办法将其快捷方式划分为这些虚线(?):
var_dump( every( $players )->score );
every( $players )->score += 40;
由于我没有看到php这样的功能,有没有办法实现它?
我使用php作为主要语言提出问题,但language-agnostic和programming-languages代表问题的第二部分:支持此类语言的语言或至少类似的简写?
答案 0 :(得分:2)
所以,你是正确的,PHP不支持这种“开箱即用”(除了有点,见下文)。我所知道的第一种语言是Objective-C(好吧,至少是CoreFoundation库)。 NSArrays和其他集合都有方法(在一行中)指示a given method should be executed on all members;甚至更酷(至少对我来说)是“keypaths”和support that NSArray以及其他人对它们的概念。一个例子;假设你有一群“人”,每个人都有一个父母,而父母又有一个“名字”:
arrayOfNames = [peopleArray valueForKeyPath:"parent.name"];
arrayOfNames现在是所有父母姓名的数组。
PHP最接近的是array_map,您可以将它与匿名函数一起使用,以便快速地将某些内容组合在一起。
编辑轶事,可能应该记住,如果只有一个语句要执行,那么循环结构不会需要他们的花括号;所以任何更高级的解决方案都需要与之竞争:
foreach($players as $p) $p->score += 40;
我会为那些OOP粉丝提及一个更深入的解决方案......如果你使用集合对象而不是数组,世界就是你的牡蛎,有这样的东西。想到的最简单的概念是php的神奇__call()
方法。如何简单地迭代您的成员并为您的用户拨打电话?对于更多的控件,您可以实现一些不同的迭代策略(一个用于转换,一个用于过滤器等。差异是返回的内容,基本上)。所以理论上你可以创建一些不同的迭代器类,并在你的“main”集合类中实现一些方法来获取其中一个,这些方法将使用内容进行预初始化:
$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);
答案 1 :(得分:1)
你可以这样做:
var_dump(array_map(function($el){return $el->score;}, $players));
array_walk($players, function($el) {$el->score += 40;});