gpt4 book ai didi

javascript - 逐步执行功能时遇到麻烦,减少了一系列功能

转载 作者:行者123 更新时间:2023-11-30 10:02:30 25 4
gpt4 key购买 nike

当在函数数组上使用reduce方法时,我很难找到reduce在数组上的工作方式。

comboFunc(num, functionsArr) {
return functionsArr.reduce(function (last, current) {
return current(last);
}, input);
}


因此,在 functionsArr = [add, multi]和函数 addmulti

function add(num) {
return num + 1;
}




function multi(num) {
return num * 30;
}


函数 comboFunc将:

comboFunc(2, functionsArr); //returns 90;


我了解通过对数组的每个元素应用函数,reduce方法如何在将数字折叠为一个值的数字数组上工作。这个带有comboFunc的示例将函数数组作为参数使用了足够简单的数学,我可以理解reduce如何在数学上产生90的值,但是我不了解逐行以及在功能级别的每次迭代中发生了什么。我无法清楚地说明什么时候发生了什么--输入2是如何从函数传递到函数的-闭包以及每个函数的顺序触发等。

如果reduce方法将传递给函数的函数应用于数组的每个元素,并且当数组中的每个元素都是函数时,我该如何从语法上写出自己的理解呢?

传递给reduce方法的函数返回 current(last),这是一个返回函数的函数。这样会使 last等于 add函数,而 current等于 multi吗?换句话说,返回 multi(add)?如果我的逻辑是正确的,那么这意味着发生了什么事情,然后将输入传递给 add并进行计算,然后将返回值传递给 multi并进行计算以最终返回90?

最佳答案

看来您正在尝试创建一个composition函数,该函数需要将一系列函数应用于输入num

让我们首先介绍几个语法错误。首先,您缺少function关键字

// your code
comboFunc(num, functionsArr) {

// should be
function comboFunc(num, functionsArr) {


接下来,您已将参数命名为 num,但随后在函数体中将其引用为 input

// your code
}, input);

// should be
}, num);


因此,在解决此问题之后,您的功能就可以使用,但是如果我们对问题的处理方式有所不同怎么办?


  免责声明:此答案不会引导您完成所提供的功能。相反,它通过演示 comboFunc过于复杂的方式来同情您的难度。反过来,我为您提供了功能的替代定义,其功能相同,但更易于阅读/理解。


首先,我认为我们应该回到功能组合的基础。

我喜欢将功能组合描绘成一张小地图。

  f(x)=y      g(y)=z
+--------> y -------+
| |
| |
| v
x ----------------> z
?


在上面的示例中,我们可以轻松地用您的 add函数替换f,并用您的 multi函数替换g。定义?现在也应该很明显。

  add(2)      multi(3)
+--------> 3 -------+
| |
| |
| v
2 ----------------> 90
h(x) = g(f(x)) = z
h(x) = (g∘f)(x) = z
h(2) = 90


(g∘f)可以说是“ g of f”,它的意思是先将x应用于f,然后将结果应用于g。

注意y甚至不存在。我们已经根据x定义了h,它使我们可以直接映射到z,完全跳过y。

将两个函数组合在一起是非常基本的操作,我们可以定义一个函数轻松完成此操作

function comp(g,f) {
return function(x) {
return g(f(x));
}
}

var h = comp(multi,add);

h(2); // 90
// h(2) = multi(add(2)) = 90


“是的,但是我正在尝试使用N个功能。不只是2个。”

好的, comp可用于两个功能,但是我已经简化了这个问题。您可能想知道如果我们想一起组成3、4甚至更多的函数,这将如何工作。

好,让我们再看一遍

a(w)              = x
b(x) = y
c(y) = z
d(w) = c(b(a(w))) = z
d(w) = (c∘b∘a)(w) = z


仔细观察 。我们知道这是我们的 comp函数,我们可以看到它出现在每个函数a,b,c之间。

在继续之前,假设我们有一个数字数组

var xs = [1,2,3];


如果要对数字求和,则需要调用

var sum = 1 + 2 + 3


看看 +在每个数字之间如何显示?使用我们的一系列功能,这没有什么不同!

var fs = [c,b,a];
var d = (c ∘ b ∘ a)


我们只需要制作有效的JavaScript。这也很容易,因为我们已经将 定义为 comp

列表中各项之间的函数调用称为线性 fold,而JavaScript具有执行此功能的函数称为 reduce

好吧,让我们使用它吧!我们将使用 comp函数折叠(“减少”)函数列表

function compN(fs) {
return fs.reduce(comp);
}

var h = compN([multi, add]);

h(2); // 90
// h(2) = multi(add(2)) = 90
// h(2) = (multi ∘ add)(2) = 90


好的,所以它可以用于我们原来的两个功能,但是请确保它可以使用更长的列表

var i = compN([multi, add, add, add]);

i(2); // 150
// i(2) = multi(add(add(add(2))) = 150
// i(2) = (multi ∘ add ∘ add ∘ add)(2) = 150



  好,让我们来回顾一下


function add(num) {
return num + 1;
}

function multi(num) {
return num * 30;
}

function comp(g,f) {
return function(x) {
return g(f(x));
}
}

function compN(fs) {
return fs.reduce(comp);
}

compN([multi, add])(2); // 90


“但是为什么更好呢?”

就像我们在 y中切出 h(x) = (g∘f)(x) = z一样,请注意 compN函数与 numlastcurrent无关。我们已经删除了3个变量供大脑思考,更清楚地知道我们的功能在做什么。

comp取f和g一起组成 g ∘ f

compN在功能列表的每个术语之间调用 comp

对我来说,这是非常简单和容易理解的。只需查看每个 compcompN的功能主体,我就可以立即确定意图。


  比较一下


comboFunc(num, functionsArr) {
return functionsArr.reduce(function (last, current) {
return current(last);
}, input);
}


难怪您很难遵循它。 comboFunc从一开始就非常关注自己,因为它试图成为两个操作而不是一个操作。

因此,我知道我没有一步一步地介绍您的原始功能,但是我希望阅读完此答案后,您对功能组成有更多的了解,并且可以单独解决各个问题。



编辑

根据下面的讨论,对于我们的 compN函数,在空数组 []上工作非常有价值。

var f = compN([]);
// Uncaught TypeError: Reduce of empty array with no initial value


!这里的预期行为将用于 compN创建一个返回未修改输入的函数。

function id(x) {
return x;
}


将其用作reduce的起点将确保即使给出空数组,我们的 compN函数也将起作用

// revised compN
function compN(fs) {
return fs.reduce(comp, id);
}


一探究竟

compN([])(2);           // 2
compN([multi, add])(2); // 90


现在 compN将适用于包含0个或多个函数的数组。

关于javascript - 逐步执行功能时遇到麻烦,减少了一系列功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30828461/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com