【问题标题】:indexed array foreach shorthand索引数组 foreach 速记
【发布时间】:2012-08-31 15:21:34
【问题描述】:

数据:

$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;

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

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

【问题讨论】:

    标签: for foreach php php language-agnostic programming-languages php loops language-agnostic programming-languages


    【解决方案1】:

    所以,你是正确的,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()方法。迭代您的成员并为您的用户发出调用有多简单?为了获得更多控制,您可以实现几种不同的迭代策略(一种用于转换,一种用于过滤器等。本质上,差异是返回的内容)。所以理论上你可以创建几个不同的迭代器类,并在你的“主”集合类中实现几个方法来获取其中一个,这些方法将使用内容进行预初始化:

    $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);
    

    【讨论】:

    • "NSArrays 和其他集合有方法..." 对这些方法有什么参考吗?
    • 我添加了指向答案的链接。如果您在概念层面上对此有所了解,您可能还会真正挖掘他们的键值编码,它在所有地方都非常深入地集成,然后他们的“键值观察”(还不是 iOS)的实现添加权力的灵活性。我最喜欢的关于所有这些的 Cocoa 实现(以及一般的 OOP/设计模式)的读物之一:amazon.com/Cocoa-Design-Patterns-Erik-Buck/dp/0321535022/…
    【解决方案2】:

    你可以这样做:

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

    【讨论】:

    • 嗯,是的,但它的表现力不如预期。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    相关资源
    最近更新 更多