我如何使用 PHP 5.3 闭包,就像我们在 Ruby 中使用块一样

发布于 2024-09-12 01:18:14 字数 465 浏览 5 评论 0原文

我如何使用 PHP 5.3 闭包,就像我们在 Ruby 中使用块一样。 我从未在 Ruby 中使用过“for”循环,因为使用带有“each”“find_all”“inject”方法的块。

我如何使用 PHP 5.3 闭包(如 Ruby 块)并告别“for”循环:)

就像 { 和 } 之间是一个闭包(或块或匿名函数)一样

fruit = %w[apple banana orange]
fruit.each { |f| print "#{f}, " }

,我在 PHP 中这样做,

$fruit = array('apple', 'banana', 'orange');
foreach ($fruit as $f) 
{
 print "$f, "; 
}

有没有办法使用 PHP 闭包以 Ruby 方式执行此操作,因为 PHP 5.3 支持它。

How can I use PHP 5.3 Closures like We use Blocks in Ruby.
I never used 'for' Loop in Ruby due to using Blocks with 'each' 'find_all' 'inject' Methods.

How can I use PHP 5.3 Closures like Ruby Blocks and say bye-bye to 'for' Loops :)

Like Between { and } is a Closure(or Block or Anonymous Function)

fruit = %w[apple banana orange]
fruit.each { |f| print "#{f}, " }

I do it in PHP this way,

$fruit = array('apple', 'banana', 'orange');
foreach ($fruit as $f) 
{
 print "$f, "; 
}

Is there a way to do this the Ruby way using PHP Closures as PHP 5.3 supports it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你爱我像她 2024-09-19 01:18:14

如果您正在考虑使用 lambda 来迭代 PHP 数组,则可以使用某些函数来完成此任务。为了更好地说明这一点,我使用了一个包装类 enum

class enum {
    public $arr;

    function __construct($array) {
        $this->arr = $array;
    }

    function each($lambda) {
        array_walk($this->arr, $lambda);
    }

    function find_all($lambda) {
        return array_filter($this->arr, $lambda);
    }

    function inject($lambda, $initial=null) {
        if ($initial == null) {
            $first = array_shift($this->arr);
            $result = array_reduce($this->arr, $lambda, $first);
            array_unshift($this->arr, $first);

            return $result;
        } else {
            return array_reduce($this->arr, $lambda, $initial);
        }
    }

}


$list = new enum(array(-1, 3, 4, 5, -7));
$list->each(function($a) { print $a . "\n";});

// in PHP you can also assign a closure to a variable 
$pos = function($a) { return ($a < 0) ? false : true;};
$positives = $list->find_all($pos);

// inject() examples
$list = new enum(range(5, 10));

$sum = $list->inject(function($sum, $n) { return $sum+$n; });
$product = $list->inject(function($acc, $n) { return $acc*$n; }, 1);

$list = new enum(array('cat', 'sheep', 'bear'));
$longest = $list->inject(function($memo, $word) {
        return (strlen($memo) > strlen($word)) ? $memo : $word; }
    );

也就是说,PHP 中的闭包并不意味着要取代 for 循环,它们的行为也不像 ruby​​ 块。

If you are looking at using lambdas to iterate over a PHP array, there are certain functions that you could use to accomplish that. Better illustrate it, I used a wrapper class enum:

class enum {
    public $arr;

    function __construct($array) {
        $this->arr = $array;
    }

    function each($lambda) {
        array_walk($this->arr, $lambda);
    }

    function find_all($lambda) {
        return array_filter($this->arr, $lambda);
    }

    function inject($lambda, $initial=null) {
        if ($initial == null) {
            $first = array_shift($this->arr);
            $result = array_reduce($this->arr, $lambda, $first);
            array_unshift($this->arr, $first);

            return $result;
        } else {
            return array_reduce($this->arr, $lambda, $initial);
        }
    }

}


$list = new enum(array(-1, 3, 4, 5, -7));
$list->each(function($a) { print $a . "\n";});

// in PHP you can also assign a closure to a variable 
$pos = function($a) { return ($a < 0) ? false : true;};
$positives = $list->find_all($pos);

// inject() examples
$list = new enum(range(5, 10));

$sum = $list->inject(function($sum, $n) { return $sum+$n; });
$product = $list->inject(function($acc, $n) { return $acc*$n; }, 1);

$list = new enum(array('cat', 'sheep', 'bear'));
$longest = $list->inject(function($memo, $word) {
        return (strlen($memo) > strlen($word)) ? $memo : $word; }
    );

That being said, closures in PHP aren't meant to replace the for loop nor do they behave like ruby blocks.

川水往事 2024-09-19 01:18:14

我认为 array_map() 和 array_walk() 作为 RubyBlocks 的替代品看起来更好。

I think array_map() and array_walk() look better as RubyBlocks replacement.

相思故 2024-09-19 01:18:14

我不认为匿名函数可以替代 for 循环,我也不认为有必要用它们替换 for 循环。

它的用处是回调。以此为例:
(是的,这是一个蹩脚的冒泡排序,但它只是一个例子)

<?php

function bubble_sort($sort_rule, $elements) {
    do {
        $swapped = false;
        for ($i = 0; $i < count($elements) - 1; $i++) {
            if ($sort_rule($elements[$i], $elements[$i + 1])) {
                $elements[$i] ^= $elements[$i + 1];
                $elements[$i + 1] ^= $elements[$i];
                $elements[$i] ^= $elements[$i + 1];
                $swapped = true;
            }
        }
    } while($swapped);
    return $elements;
}

print_r(bubble_sort(function ($a, $b) { if ($a > $b) return true; else return false; }
,array(1,6,3,7,42,-1,0,6)));
?>

在像 php 这样的过程编程语言中,闭包并不能替代 for 循环。当然,如果您使用 lisp 或方案,它们是,但这是不必要的。

您可以这样编写它们,您真正要做的就是创建一个内部带有 for 循环的匿名函数。我认为如果使用 for 循环可以轻松完成任务,那么递归就没有必要了,因此您不会与 for 循环吻别。

当您想快速定义回调方法时,匿名函数在事件驱动编程中也非常有用。

I don't think an anonymous function is a substitute for a for loop, nor do I think it's necessary to replace for loops with them.

What it is useful for is a callback. Take this for example:
(yes, it is a lame bubble sort, but it is an example)

<?php

function bubble_sort($sort_rule, $elements) {
    do {
        $swapped = false;
        for ($i = 0; $i < count($elements) - 1; $i++) {
            if ($sort_rule($elements[$i], $elements[$i + 1])) {
                $elements[$i] ^= $elements[$i + 1];
                $elements[$i + 1] ^= $elements[$i];
                $elements[$i] ^= $elements[$i + 1];
                $swapped = true;
            }
        }
    } while($swapped);
    return $elements;
}

print_r(bubble_sort(function ($a, $b) { if ($a > $b) return true; else return false; }
,array(1,6,3,7,42,-1,0,6)));
?>

Closures aren't a replacement for for loops in a procedural programming language like php. Sure if you're using lisp or scheme they are, but that's out of necessity.

You can write them that way, all you'll really be doing is creating an anonymous function with a for loop inside it. I think recursion would just be unnecessary if the task is just as easily accomplished with a for loop, and therefore you're not kissing for loops good bye.

Anonymous functions are very useful in event driven programming as well, when you want to just define a callback method really quick.

我还不会笑 2024-09-19 01:18:14

简单的回答:你不知道。 Ruby 并非没有 for() 循环,它们只是屏蔽了单词“for”并稍微改变了语法。如果你想使用闭包,它只是一个内部有循环的闭包,或者是一个丑陋的(而且效率较低的)递归闭包。

闭包与块不同。闭包类似于 JavaScript 中的函数——也就是说,它们可以存储在变量中并作为参数发送。

Simple answer: you don't. Ruby is not devoid of for() loops, they just mask the word "for" and change the syntax a bit. If you wanted to use a closure, it'd just be a closure with a loop inside it, or an ugly (and less efficient) recursive closure.

And closures are NOT the same thing as blocks. Closures are comparable to functions in JavaScript-- that is, they can be stored in variables and sent as arguments.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文