升级php后网站变得很慢
Have you heard of functional programming, high order functions, etc. before? Probably, right? However, when you hear “transducers”, do you know what those are?
您以前听说过函数式编程 ,高阶函数等吗? 大概吧 但是,当您听到“换能器”时,您知道它们是什么吗?
换能器的定义 (The Definition of Transducers)
We can’t define transducers without talking about reducers first. Quoting Rich Hickey:
我们必须先讨论减速器才能定义换能器。 引用Rich Hickey :
A reducing function is just the kind of function you’d pass to reduce – it takes a result so far and a new input and returns the next result-so-far.
约简函数只是您要传递的那种约简函数,它需要到目前为止的结果和新的输入,并立即返回下一个结果。
A transducer is a function that takes one reducing function and returns another.
换能器是一种功能,具有一个归约功能,另一个归还功能。
Transducers were first introduced into Clojure by Rich Hickey, and ported to PHP by Michael Dowling. Transducers are a powerful way to build algorithmic transformations that you can reuse in many contexts. In this article, we’re going to take a look at how they could be useful through a set of practical examples.
Rich Hickey首先将换能器引入Clojure ,然后由Michael Dowling 移植到PHP 。 换能器是一种构建算法转换的强大方法,您可以在许多情况下重复使用。 在本文中,我们将通过一组实际示例来研究它们如何有用。
例子 (Examples)
We need to install the Transducers package via Composer before going any further.
我们需要通过Composer安装Transducers软件包,然后再进行任何操作。
composer require mtdowling/transducers
We’ll use a simple User class for the following examples.
下面的示例将使用一个简单的User类。
class User
{
public $id;
public $name;
public $age;
public function __construct($id, $name, $age)
{
$this->id = $id;
$this->name = $name;
$this->age = $age;
}
public function __toString()
{
return sprintf("\n%d - %s - %d", $this->id, $this->name, $this->age);
}
}
// demo data
$data = [
new User(1, "younes", 24),
new User(2, "youssef", 26),
new User(3, "hamza", 25),
new User(4, "ismail", 17),
];
use Transducers as t;
$uppercase = t\map(function($user) {
return new User($user->id, ucfirst($user->name), $user->age);
});
$result = t\xform($data, $uppercase);
var_dump($result);
The map function is similar to the array_map PHP function: we pass a callable which, in this case, will uppercase the first letter of the user name.
map函数类似于array_map PHP函数:我们传递了一个callable ,在这种情况下,它将用户名的第一个字母大写。
We use the xform function to apply our uppercase transducer. It takes our data for the first parameter and a transducer for the second.
我们使用xform函数来应用我们的uppercase转换器。 它使用我们的数据作为第一个参数,并使用传感器作为第二个参数。
// output
array(4) {
[0]=>
object(User)#14 (3) {
["id"]=>
int(1)
["name"]=>
string(6) "Younes"
["age"]=>
int(24)
}
[1]=>
object(User)#15 (3) {
["id"]=>
int(2)
["name"]=>
string(7) "Youssef"
["age"]=>
int(26)
}
[2]=>
object(User)#16 (3) {
["id"]=>
int(3)
["name"]=>
string(5) "Hamza"
["age"]=>
int(25)
}
[3]=>
object(User)#17 (3) {
["id"]=>
int(4)
["name"]=>
string(6) "Ismail"
["age"]=>
int(17)
}
}
xform returns the same type as the data parameter (array in this case). We can also use to_array if you strictly want to output an array.
xform返回与data参数相同的类型(在这种情况下为数组)。 如果您严格要输出数组,我们也可以使用to_array 。
// ...
$result = t\to_array($data, $uppercase);
// ...
We can use to_string as well, to convert the output to a string, or into($target, $coll, callable $xf) to convert the output to a specific type. Check the documentation for more details.
我们也可以使用to_string将输出转换为字符串,或者使用into($target, $coll, callable $xf)将输出转换为特定类型。 查看文档以获取更多详细信息。
use Transducers as t;
$uppercase = t\map(function($user) {
return new User($user->id, ucfirst($user->name), $user->age);
});
$result = t\to_string($data, $uppercase);
var_dump($result);
// output
string(64) "
1 - Younes - 24
2 - Youssef - 26
3 - Hamza - 25
4 - Ismail - 17"
The best part about Transducers is that we can compose multiple transformations into a single transducer. For instance, let’s uppercase the first letter of the user name and remove minors.
关于传感器的最好的部分是我们可以将多个变换组合成一个传感器。 例如,让我们将用户名的首字母大写并删除未成年人。
$uppercase = t\map(function($user) {
return new User($user->id, ucfirst($user->name), $user->age);
});
$removeMinors = t\filter(function($user) {
return $user->age >= 18;
});
$comp = t\comp(
$uppercase,
$removeMinors
);
$result = t\to_string($data, $comp);
var_dump($result);
The filter function is similar to the array_filter PHP function. The comp function creates a transducer from a list of transducers, in this case uppercase (using map) and removeMinors (using filter).
filter函数类似于array_filter PHP函数。 comp函数从换能器列表创建一个换能器,在这种情况下为uppercase (使用map )和removeMinors (使用filter )。
// output
string(48) "
1 - Younes - 24
2 - Youssef - 26
3 - Hamza - 25"
Now we have a reusable transducer composition that we can use whenever we want to reduce our data using this criteria. Check out the documentation for the list of available reducing functions.
现在,我们有了可重用的换能器组合,只要我们希望使用此标准来减少数据,就可以使用它。 请查阅文档以获取可用的归约功能列表。
创建换能器 (Creating a Transducer)
A reducing function takes a value as a parameter and returns a reducing function array, which must contain three elements:
约简函数将值作为参数并返回约简函数数组,该数组必须包含三个元素:
init: A function that returns an initial value for the transducer. It’s only called at first if no initial value is provided.init:为换能器返回初始值的函数。 如果没有提供初始值,则只会首先调用它。result: Theresultfunction is called to build the final result from the call stack.result:将调用result函数以从调用堆栈中构建最终结果。step: This is where you write your reduction logic – you may call it zero or many times depending on your reducer logic.step:在此处编写归约逻辑-根据归约器逻辑,可以将其称为零或多次。
This becomes really confusing without showing some actual code, so let’s use the take transducer function as an example. It takes n items from the top of the data array.
在没有显示任何实际代码的情况下,这变得非常混乱,因此让我们以take换能器功能为例。 它从数据数组的顶部获取n项目。
// ....
$comp = t\comp(
$uppercase,
$removeMinors,
t\take(2)
);
$result = t\to_string($data, $comp);
var_dump($result);
// output
string(33) "
1 - Younes - 24
2 - Youssef - 26"
Here is the take reducer function’s source code.
这里是take减速功能的源代码。
function take($n)
{
return function (array $xf) use ($n) {
$remaining = $n;
return [
'init' => $xf['init'],
'result' => $xf['result'],
'step' => function ($r, $input) use (&$remaining, $xf) {
$r = $xf['step']($r, $input);
return --$remaining > 0 ? $r : ensure_reduced($r);
}
];
};
}
The take function is being called several times with the result and the input parameters. On every call, it decrements the remaining variable and tests if it’s less than zero. In that case, we return a Reduced object instance, which indicates a stopping point.
将使用result和input参数多次调用take函数。 在每次调用时,它都会减少remaining变量并测试其是否小于零。 在这种情况下,我们将返回一个Reduced对象实例,该实例指示一个停止点。
Our transducer function example will drop null elements from the data. Using the previous explanation of how transducers work, we can access the $input variable, and decide whether to call the next step callback or simply return the value.
我们的传感器功能示例将从数据中删除空元素。 使用的换能器是如何工作的前面的解释,我们可以访问$input变量,并决定是否要调用下一个step回调或简单的返回值。
function dropNull()
{
return function (array $xf) {
return [
'init' => $xf['init'],
'result' => $xf['result'],
'step' => function ($result, $input) use ($xf) {
return $input === null
? $result
: $xf['step']($result, $input);
}
];
};
}
We can test this by adding some null items to our $data variable.
我们可以通过在$data变量中添加一些null项目来进行测试。
$data = [
null,
new User(1, "younes", 24),
new User(2, "youssef", 26),
new User(3, "hamza", 25),
new User(4, "ismail", 17),
null
];
$result = t\to_string($data, t\dropNull());
var_dump($result);
// output
string(64) "
1 - younes - 24
2 - youssef - 26
3 - hamza - 25
4 - ismail - 17"
结论 (Conclusion)
In this article, we got acquainted with a new aspect of the functional programing world called transducers. We’ve gone over the purpose of transducers, which is to make the transformation of data easier. We also went over some examples to better demonstrate the value of transducers. You now have a new tool in your developer belt or, at least, a better understanding of the transducer concept.
在本文中,我们熟悉了功能编程领域的一个新方面,即换能器。 我们已经超越了换能器的目的,即使数据转换更容易。 我们还研究了一些示例,以更好地演示换能器的价值。 现在,您可以在显影带中使用新工具,或者至少可以更好地理解换能器的概念。
If you have any questions about transducers, you can post them below!
如果您对换能器有任何疑问,可以在下面发布!
翻译自: https://www.sitepoint.com/transducers-in-php-explained-and-demonstrated/
升级php后网站变得很慢
本文介绍了PHP中的换能器概念,一种强大的数据转换工具,允许开发者构建可复用的算法。文章通过实际示例展示了如何使用换能器进行数据处理,如用户名首字母大写、过滤未成年人等操作。

3887

被折叠的 条评论
为什么被折叠?



