gpt4 book ai didi

Recursive Lambda Functions for Cartesian Products in Google Sheets(Google Sheet中笛卡尔乘积的递归Lambda函数)

转载 作者:bug小助手 更新时间:2023-10-25 23:27:55 27 4
gpt4 key购买 nike



Background:


For Learning Purposes, can someone please breakdown the following formula and help me understand how this works? I am wanting to learn the code pattern to create a cartesian product array (ie. a normalised array with every combination of N columns). From what I can see, its a lot of recursive lambda's being used, but I just cant wrap my mind around how it works, so hoping that someone can explain this to me.

为了便于学习,有没有人能把下面的公式分解一下,并帮助我理解它是如何工作的?我想学习代码模式,以创建一个笛卡尔产品阵列(即。具有N列的每一组合的归一化阵列)。据我所知,它使用了很多递归的lambda,但我就是不能理解它是如何工作的,所以希望有人能给我解释一下。


Code Sample:


This is from the original source here - please scroll down to the section that says "Update April 2023"

这是从这里的原始来源-请向下滚动到“更新2023年4月”的部分


=let( 
table, A2:C,
blank, iferror(1/0),
first_, lambda(array, tocol(choosecols(array, 1), true)),
rest_, lambda(n, choosecols(table, sequence(1, columns(table) - n, n + 1))),
wrap_, lambda(array, wrapCount, wraprows(tocol(array, 1), wrapCount)),

cartesian_, lambda(a, b, wrap_(
byrow(a, lambda(row,
reduce(blank, sequence(rows(b)), lambda(acc, i,
{ acc, row, chooserows(b, i) }
) )
) ),
columns(a) + columns(b)
) ),

iterate_, lambda(
self, a, b, if(iserror(b), a,
self(self, cartesian_(a, first_(b)), rest_(columns(a) + 1))
)
),

iterate_(iterate_, first_(table), rest_(1))
)

Input Data:


Below table is from columns A -> C (as per code above, see "Table" Variable of Lambda)

下表来自A->C列(根据上面的代码,请参见Lambda的“Table”变量)

































Product Country Date
ABC001 UK 9/4/2023
US 9/11/2023
AU 9/18/2023
9/25/2023

Output Data:









































































Product Country Date
ABC001 UK 9/4/2023
ABC001 UK 9/11/2023
ABC001 UK 9/18/2023
ABC001 UK 9/25/2023
ABC001 US 9/4/2023
ABC001 US 9/11/2023
ABC001 US 9/18/2023
ABC001 US 9/25/2023
ABC001 AU 9/4/2023
ABC001 AU 9/11/2023
ABC001 AU 9/18/2023
ABC001 AU 9/25/2023

更多回答
优秀答案推荐

First of all, let’s take a moment to thank goodness for the LET function that allows us to use named expressions. Without it, this business would have to be written like this with every named expression replaced with its definition:

首先,让我们花一点时间感谢允许我们使用命名表达式的let函数。如果没有它,这项业务将不得不这样编写,每个命名表达式都将替换为其定义:


=lambda(self, a, b, 
if(iserror(b), a, self(self, lambda(a, b, lambda(array, wrapCount, wraprows(tocol(array, 1), wrapCount))
(byrow(a, lambda(row, reduce(iferror(1/0), sequence(rows(b)),
lambda(acc, i, {acc, row, chooserows(b, i)})))), columns(a) + columns(b)))
(a,lambda(array, tocol(choosecols(array, 1), true))(b)),
lambda(n, choosecols(A2:C, sequence(1, columns(A2:C) - n, n + 1)))(columns(a) + 1))))
(lambda(self, a, b,
if(iserror(b), a, self(self, lambda(a, b, lambda(array, wrapCount, wraprows(tocol(array, 1), wrapCount))
(byrow(a, lambda(row, reduce(iferror(1/0), sequence(rows(b)),
lambda(acc, i, {acc, row, chooserows(b, i)})))), columns(a) + columns(b)))
(a, lambda(array, tocol(choosecols(array, 1), true))(b)),
lambda(n, choosecols(A2:C, sequence(1, columns(A2:C) - n, n + 1)))(columns(a) + 1)))),
lambda(array, tocol(choosecols(array, 1), true))(A2:C),
lambda(n, choosecols(A2:C, sequence(1, columns(A2:C) - n, n + 1)))(1))

That said, let's now look at each named expression within the LET function to see what they do, and how this overall formula comes together to produce its result.

也就是说,现在让我们看看let函数中的每个命名表达式,看看它们做了什么,以及这个整体公式是如何组合在一起产生其结果的。


table - A2:C - This is nothing more than a specified range of cells. In this case, it starts at the second row of column A, and since no row is specified in the second argument, it continues all the way to the end of column C.

TABLE-A2:C-这只不过是指定的单元格范围。在本例中,它从列A的第二行开始,由于在第二个参数中没有指定行,因此它一直持续到列C的末尾。


blank - iferror(1/0) - The IFERROR formula uses the syntax IFERROR(test_value, [value_if_error]) Where the first argument is the test expression, and the second argument is what to return if the test expression evaluates to True. The second argument is optional, and since it isn’t used in this case, the result will be a blank cell being returned if the test condition evaluates to True. Since the first argument in this case is 0/1, the error #DIV/0 is going to occur no matter what, and consequently, a blank value will be always be returned. As we will see later, this is going to be used in the cartesian_ function to create a “blank” accumulator starting point.

BLACK-IFEREROR(1/0)-IFERROR公式使用语法IFERROR(TEST_VALUE,[VALUE_IF_ERROR]),其中第一个参数是测试表达式,第二个参数是测试表达式求值为True时返回的内容。第二个参数是可选的,由于在本例中没有使用它,如果测试条件的计算结果为True,则结果将是返回一个空白单元格。由于本例中的第一个参数是0/1,因此无论如何都会出现错误#DIV/0,因此总是返回空值。正如我们稍后将看到的,这将在Cartesian_函数中使用,以创建一个“空白”累加器起点。


first_ - lambda(array, tocol(choosecols(array, 1), true)) - Ultimately, this will be either be the first column of the table during the first iteration of the iterate_ function, or it will be the first column of the remaining columns from the _rest function during all subsequent iterations. Before we go any further, let's explain the LAMBDA function because we'll be seeing it a lot. It is a way to create a formula expression where variables are created in the first and middle arguments with last argument being reserved for the expression that uses the variables. In this example, the variable is array, and the expression is tocol(choosecols(array, 1), true). The TOCOL function takes three arguments: an array or a range of cells, an optional integer argument that specifies what to ignore that if left out will default to ignore nothing, and a Boolean argument to determine whether or not to scan by column or row with the default being scan by row. In this case, nothing is ignored [because the second argument is blank], and the scan method is by column [because the third argument is true]. The first argument of the TOCOL function [array or range] is specified using a nested function: choosecols(array, 1). The CHOOSECOLS function is pretty straightforward. The first argument is a range of cells, and each additional argument is the number of a column to return from that range of cells. It is not zero indexed, so 1 represents the very first column of the array. Putting it all together: the first_ function takes the first column of a range of cells as an array, and then, the tocol function returns it as a single column.

First_-lambda(数组,协议(Choosecols(array,1),true))-最终,这将是迭代_函数第一次迭代期间表的第一列,或者是所有后续迭代期间_rest函数剩余列的第一列。在我们继续之前,让我们先解释一下lambda函数,因为我们会经常看到它。这是一种创建公式表达式的方法,其中变量在第一个和中间参数中创建,最后一个参数保留给使用变量的表达式。在本例中,变量为ARRAY,表达式为COLICATE(Choosecols(ARRAY,1),True)。TOCOL函数有三个参数:一个数组或一个单元格区域;一个可选的整数参数,它指定要忽略的内容,如果省略它,则默认为不忽略任何内容;还有一个布尔参数,用于确定是按列还是按行扫描,默认设置为逐行扫描。在这种情况下,不会忽略任何内容[因为第二个参数为空],并且扫描方法是By Column[因为第三个参数为真]。TOCOL函数[ARRAY或RANGE]的第一个参数是使用嵌套函数指定的:Choosecols(ARRAY,1)。CHOOSECOLS函数非常简单。第一个参数是一个单元格区域,每个附加参数是从该单元格区域返回的列号。它不是零索引的,因此1表示数组的第一列。总而言之:First_函数将单元格区域的第一列作为数组,然后,协议函数将其作为单列返回。


rest_ - lambda(n, choosecols(table, sequence(1, columns(table) - n, n + 1))) - In this LAMBDA function, n is the variable, and choosecols(table, sequence(1, columns(table) - n, n + 1)) is the expression. The columns chosen from the input table by the CHOOSECOLS function will be determined by sequence(1, columns(table) - n, n + 1). The COLUMNS function simply returns the number of columns within a specified array or range, so in this case, the range is the entire table which consists of three columns, and the actual SEQUENCE function will evaluate to sequence(1, 3 - n, n + 1) With this function there are four possible arguments: number of rows to return, number of columns to return, the number to start the sequence at, and the amount to step the sequence by. The last three arguments are optional and all default to 1. Since the fourth argument is omitted in this case, the sequence will step by 1. Therefore, the number of columns to return will be the total number of columns in the table minus n, and the starting point will be n +1. Putting it all together: If n = 1 then, in this case, the number of columns returned would be 3 – 1 = 2, and the starting point would be 1 + 1 = 2, so the columns chosen from the table would be columns 2 and 3. Likewise if n were 2, then the number of columns returned would only be one, and the starting point would be 3, so the chosen column would be 3. However, if n were to equal 3, the number of columns to return would be zero, which is good because the starting point would calculate to 4, and that’s not possible with only three columns. It should also be noted that unlike the first_ function that will always return the first column, this one will never return the first column. As I’ve demonstrated above, it can only return the remaining columns. Hence the name rest, which we can interpret as the rest of the columns.

Rest_-lambda(n,Choosecols(TABLE,SEQUENCE(TABLE,COLUMNS(TABLE)-n,n+1)-在这个Lambda函数中,n是变量,Choosecols(TABLE,SEQUENCE(1,Columns(TABLE)-n,n+1))是表达式。CHOOSECOLS函数从输入表中选择的列将按顺序(1,Columns(TABLE)-n,n+1)确定。COLUMNS函数只返回指定数组或范围内的列数,因此在本例中,范围是由三列组成的整个表,而实际的序列函数将计算为SEQUENCE(1,3-n,n+1)。使用此函数,有四个可能的参数:要返回的行数、要返回的列数、要开始序列的数目和序列的步进量。最后三个参数是可选的,并且都默认为1。由于在本例中省略了第四个参数,因此序列将按1步进。因此,要返回的列数将是表中的总列数减去n,起点将是n+1。总而言之:如果n=1,则在本例中,返回的列数将是3-1=2,起点将是1+1=2,因此从表中选择的列将是列2和3。同样,如果n是2,则返回的列数将仅为1。起始点是3,所以选择的列数是3。但是,如果n等于3,则返回的列数将为0,这很好,因为起始点将计算到4,而这在只有3列的情况下是不可能的。还需要注意的是,与总是返回第一列的First_Function不同,这个函数永远不会返回第一列。正如我在上面所演示的,它只能返回剩余的列。因此命名为REST,我们可以将其解释为其余的列。


wrap_ - lambda(array, wrapCount, wraprows(tocol(array, 1), wrapCount)) - First of all, note that this LAMBDA function has two variables: array and wrapCount. Both are needed because the expression argument uses the WRAPROWS function which requires two arguments: range and wrapcount, and there is an optional third argument for pad width that is omitted here. The range in this case will be the column returned by the TOCOL function using the variable array, but notice how the arguments being passed to this function configure it to ignore blanks and scan by row. This differs from the previous use of TOCOL in the first_ function where nothing was ignored and the scan was done by column. This means that each consecutive row of the single column that is returned will be a non-blank value from each consecutive column in the array. Finally, the WRAPROWS function will then take that single column and convert it to multiple columns. Each consecutive row will become a single row of consecutive columns until the number of columns equals the number specified by the wrapCount variable. Of course, this could seem redundant to convert multiple columns to a single column only to convert it back to multiple columns again, if it weren’t for the second argument in tocol(array, 1) that tells us that we are removing blank values, and the wrapCount variable that could be used to change the number of rows and columns. In the cartesian_ function we will explore next, we will find out that this is indeed the case, and that the nested REDUCE function will actually be encoding multiple columns into long rows that the wrap_ function will have to unpack.

wrap_ - lambda(array,wrapCount,wraprows(tocol(array,1),wrapCount))-首先,请注意这个LAMBDA函数有两个变量:array和wrapCount。这两个参数都是必需的,因为表达式参数使用WRAPROWS函数,该函数需要两个参数:range和wrappcount,还有第三个可选的填充宽度参数,这里省略了。在这种情况下,范围将是TOCOL函数使用变量数组返回的列,但请注意传递给此函数的参数如何将其配置为忽略空白并按行扫描。这与之前在first_ function中使用TOCOL不同,在first_ function中没有忽略任何内容,并且扫描是按列进行的。这意味着返回的单个列的每个连续行都将是数组中每个连续列的非空值。最后,WRAPROWS函数将获取该单列并将其转换为多列。每个连续的行都将成为连续列的单行,直到列数等于wrapCount变量指定的数字。当然,如果不是因为tocol(array,1)中的第二个参数告诉我们我们正在删除空值,以及wrapCount变量可以用于更改行数和列数,那么将多列转换为一列并再次将其转换回多列似乎是多余的。在我们接下来要探索的carpet_ function中,我们会发现确实是这样的,嵌套的REDUCE函数实际上会将多个列编码成长行,wrap_ function必须解包。


cartesian_

笛卡尔_


=lambda(a, b, wrap_( 
byrow(a, lambda(row,
reduce(blank, sequence(rows(b)), lambda(acc, i,
{ acc, row, chooserows(b, i) }
) )
) ),
columns(a) + columns(b)
) )

Now that we have a firm understanding of all the basic ingredients, it’s time to get into the core function that produces the cross products we need to pair every value from each column with every value of all the other columns. First of all, the reason this function is named cartesian_ is because the operation being performed creates a Cartesian product using the two variables [a and b] defined in the first two arguments of the LAMBDA function.

既然我们对所有基本成分都有了明确的理解,现在就该进入生成交叉积的核心函数了,我们需要将每一列的每个值与所有其他列的每个值配对。首先,将该函数命名为Cartesian_是因为执行的操作使用Lambda函数的前两个参数中定义的两个变量[a和b]创建了一个笛卡尔乘积。


At this point, the outer part of this function will be the easiest to understand. The wrap_ function we explored above will take the combined rows that are returned by the BYROW function; it will convert them to a single column removing the blank cells, and then, it will return it to the original number of columns with the wrapCount argument that comes from the last line of the cartesian function: columns(a) + columns(b), where the number of columns from each variable are simply summed to produce the total that there will be.

此时,该函数的外部部分将是最容易理解的。上面讨论的WRAP_Function将获取由BYROW函数返回的组合行;它将把它们转换为删除空单元格的单个列,然后,它将使用来自笛卡尔函数最后一行的wrapCount参数将它们返回到原始列数:Columns(A)+Columns(B),其中每个变量的列数被简单地相加,以产生将存在的总列数。


The next part to look at here is the BYROW function. As a generic function, it’s fairly intuitive in that it simply goes row by row through an array or range, and it passes each row into a single variable LAMBDA function for some kind of processing. In this case, the BYROW function is iterating through the range provided by variable a and passing each row of variable a into lambda(row, reduce(blank, sequence(rows(b)), lambda(acc, i, {acc, row, chooserows(b, i)}))), but notice how its LAMBDA function can make use of the b argument since the the BYROW function is nested in a LAMBDA function that originally took both arguments.

下一个要看的部分是BYROW函数。作为一个泛型函数,它相当直观,因为它只是逐行遍历数组或范围,并将每行传递到一个单变量LAMBDA函数中进行某种处理。在本例中,BYROW函数遍历变量a提供的范围,并将变量a的每一行传递到lambda(row,reduce(blank,sequence(rows(b)),lambda(acc,i,{acc,row,sequence(b,i)}))中,但请注意其LAMBDA函数如何利用b参数,因为BYROW函数嵌套在最初接受两个参数的LAMBDA函数中。


Inside the BYROW LAMBDA we encounter the REDUCE function. The reduce function takes three arguments: An initial value, a range or array, and a two variable LAMBDA function in which the first variable will be an accumulator that will update with the returned value from the LAMBDA’s expression and the second variable will be the current input array that is provided row by row from the REDUCE function’s array or range argument. In this case, the “initial value” argument of the REDUCE function will be the “blank” placeholder value returned from the blank function that was discussed earlier, and the “array or range” will be a sequence of numbers from 1 to the number of rows in the b range that was passed into the outermost LAMBDA function. Finally we come to the innermost part of the cartesian_ function, and that is the lambda(acc, i, {acc, row, chooserows(b, i)}) argument of the REDUCE function. This is the interesting part: {acc, row, chooserows(b, i)} As the function iterates through each index [i] of variable b, its going to take the combined values acc and add the row variable which is actually the current row in variable a that was provided by the BYROW function. Then, it’s going to use the CHOOSEROWS function to add the entire row from variable b that corresponds with index i. The result will be a long row that starts with a blank value, followed by row, followed by b[row 1], followed by row, followed by b[row 2], followed by row, followed by b[row 3], and so on and so forth until every row in b has been iterated through. Then, all of this will be returned to the outer BYROW function which will then supply its next row in variable a to repeat the process with that row. Putting it all together:, When the BYROW function has completed its iterations, the result will look like this:

在BYROW Lambda内部,我们遇到了REDUTE函数。REDUTE函数有三个参数:初始值、范围或数组,以及两个变量的Lambda函数,其中第一个变量是累加器,它将使用Lambda的表达式的返回值进行更新,第二个变量是从Reduced函数的数组或范围参数逐行提供的当前输入数组。在本例中,Reduced函数的“初始值”参数将是从前面讨论的空白函数返回的“空白”占位符值,而“数组或范围”将是从1到传递到最外面的Lambda函数的b范围内的行数的一系列数字。最后,我们来看看Cartesian_函数的最里面的部分,那就是REDUTE函数的lambda(acc,i,{acc,row,Chooserrow(b,i)})参数。这是有趣的部分:{acc,row,Chooserrow(b,i)}当函数迭代变量b的每个索引[i]时,它将获取组合值acc并添加ROW变量,该变量实际上是由BYROW函数提供的变量a中的当前行。然后,它将使用CHOOSEROWS函数将变量b中与索引i对应的整行相加。结果将是一个从空值开始的长行,接着是行,然后是b[行1],然后是行,然后是b[行2],然后是行,然后是b[行3],依此类推,直到遍历了b中的每一行。然后,所有这些都将返回给外部的BYROW函数,然后该函数将在变量a中提供其下一行,以对该行重复该过程。将所有这些放在一起:当BYROW函数完成其迭代时,结果将如下所示:


[‘’, a[row 1], b[row 1], a[row 1], b[row 2], a[row 1], b[row 3], a[row 1], b[row 4]],
[‘’, a[row 2], b[row 1], a[row 2], b[row 2], a[row 2], b[row 3], a[row 2], b[row 4]]

Note how each row starts with the blank initial value of the REDUCE function, and how each row repeats combining the a[rowIndex] variable with every row of the b variable.

注意每一行是如何以REDUTE函数的空白初始值开始的,以及每一行是如何重复将a[rowIndex]变量与b变量的每一行组合在一起的。


Moving further out, the wrap_ function passes all of this into the The TOCOL function in a way that removes the blanks and iterates row by row to produce a single column that looks like this:

再往外看,WRAP_Function将所有这些内容传递给TOCOL函数,方法是删除空格并逐行迭代,以生成如下所示的单个列:


a[row 1],
b[row 1],
a[row 1],
b[row 2],
a[row 1],
b[row 3],
a[row 1],
b[row 4],
a[row 2],
b[row 1],
a[row 2],
b[row 2],
a[row 2],
b[row 3],
a[row 2],
b[row 4]

Finally, the outermost part of the wrap_ function uses the WRAPROWS function with the combined column numbers from the columns(a) + columns(b) argument to convert the single column to this:

最后,WRAP_Function的最外层使用WRAPROWS函数和Columns(A)+Columns(B)参数中的组合列号,将单个列转换为:


[a[row 1], b[row 1]],
[a[row 1], b[row 2]],
[a[row 1], b[row 3]],
[a[row 1], b[row 4]],
[a[row 2], b[row 1]],
[a[row 2], b[row 2]],
[a[row 2], b[row 3]],
[a[row 2], b[row 4]]

iterate_ - lambda(self, a, b, if(iserror(b), a, self(self, cartesian_(a, first_(b)), rest_(columns(a) + 1))) - There are three variables in this the LAMBDA function: self [which is literally the function itself to allow for recursive calls], a [an array], and b [a second array]. The expression part is a simple IF function: if(iserror(b), a, self(self, cartesian_(a, first_(b)), rest_(columns(a) + 1))). The first argument of the IF is a boolean expression; the second argument is the value or expression to use if the first argument is True, and the third argument is the value or expression to use if the first argument is False. In this case, the test expression is the ISERROR function. ISERROR will return True if the value is an error. Since in this case our test argument is iserror(b), and our first argument is a, we know that if b fails for whatever reason the function will return a and the process is finished. However, if b does not fail, then the second argument will be called: self(self, cartesian_(a, first_(b)), rest_(columns(a) + 1)) Remember that self is literally the iterate_ function itself, so this is a recursive call. During the recursive call, the first argument is still self, so the recursion can continue until the b variable fails, but the second argument [a] is the cartesian_ function that we explored above using the resultant a value from the previous iteration as the first cartesian argument, and the first column from the resultant b value from the previous iteration as the second cartesian argument. Finally, the third argument b of the recursive iterate_ function will be the rest_ function we explored above, using the starting point of the total number of columns from the resultant a value of the previous iteration + 1.

Iterate_-lambda(self,a,b,if(iserror(B),a,self(self,Cartesian_(a,first_b)),rest_(Columns(A)+1)-Lambda函数中有三个变量:self[这实际上是允许递归调用的函数本身]、a[一个数组]和b[第二个数组]。表达式部分是一个简单的IF函数:IF(iserror(B),a,self(self,Cartesian_(a,first_(B)),rest_(Columns(A)+1)。IF的第一个参数是布尔表达式;第二个参数是第一个参数为True时使用的值或表达式,第三个参数是第一个参数为False时使用的值或表达式。在本例中,测试表达式是ISERROR函数。如果值为错误,ISERROR将返回True。因为在本例中,我们的测试参数是isError(B),而我们的第一个参数是a,所以我们知道,如果b由于任何原因失败,函数将返回a,过程结束。但是,如果b没有失败,那么第二个参数将被调用:self(self,Cartesian_(a,first_(B)),rest_(Columns(A)+1))记住,self本身就是Iterate_Function本身,所以这是一个递归调用。在递归调用期间,第一个参数仍然是self,因此递归可以继续,直到b变量失败,但第二个参数[a]是我们上面探索的Cartesian_Function,它使用上一次迭代的结果a值作为第一个笛卡尔参数,并使用前一次迭代的结果b值的第一列作为第二个笛卡尔参数。最后,递归Iterate_Function的第三个参数b将是我们上面探索的REST_Function,它使用上一次迭代的结果a值中的列总数的起点+1。


iterate_(iterate_, first_(table), rest_(1)) - Finally, the last line of the formula is actually the starting point that kicks everything off. Here, the iterate_ function is called with the second argument [a] evaluating to the first row of the table, and the second argument [b] evaluating to every column except the first column as defined in the initial explanation of the rest_ function.

_(在这里,rests_ function被调用,第二个参数[a]计算表的第一行,第二个参数[b]计算除了第一列之外的每一列,如在rests_ function的初始解释中定义的。


Putting everything together using your input example: The starting point of this formula would look like this:

使用输入示例将所有内容放在一起:此公式的起点如下所示:


First Iteration:

第一次迭代:


a = {[ABC001]}

b = {[UK, 9/4/2023],
[US, 9/11/2023],
[AU, 9/18/2023],
[‘’, 9/25/2023]}

Second Iteration: Since b is not an error, then the iteration_ function will call itself recursively, only this time, it’s using the cartesian_ function as its second argument. So the second iteration ends up with this for an a value:

第二次迭代:因为b不是错误,所以Iteration_Function将递归地调用自身,只是这一次,它使用Cartesian_Function作为它的第二个参数。因此,第二次迭代以a值结束:


a = {[ABC001, UK],
[ABC001, US],
[ABC001, AU]}

Since the third argument of the recursive iteration is rest_(columns(a) + 1), and since the number of columns from a value of the first iteration was 1 then rest(2) ends up returning column 3 from the table as demonstrated above. Therefore, b ends up evaluating to this in the second iteration:

由于递归迭代的第三个参数是REST_(Columns(A)+1),并且由于第一次迭代的值的列数是1,因此REST(2)结束时从表中返回列3,如上所述。因此,b在第二次迭代中的计算结果如下:


b = {[ 9/4/2023],
[9/11/2023],
[9/18/2023],
[9/25/2023]}

Third Iteration: Since once again b is not an error, the iteration function will get called a third time. This time the cartesian function will add every row from the b column to every row of the preceding a column, and the [a] variable will evaluate to this:

第三次迭代:由于b再一次不是错误,迭代函数将被第三次调用。这一次,笛卡尔函数将把b列中的每一行与前一列中的每一行相加,[a]变量的计算结果为:


a = {[ABC001, UK, 9/4/2023],
[ABC001, UK, 9/11/2023],
[ABC001, UK, 9/18/2023],
[ABC001, UK, 9/25/2023],
[ABC001, US, 9/4/2023],
[ABC001, US, 9/11/2023],
[ABC001, US, 9/18/2023],
[ABC001, US, 9/25/2023],
[ABC001, AU, 9/4/2023],
[ABC001, AU, 9/11/2023],
[ABC001, AU, 9/18/2023],
[ABC001, AU, 9/25/2023]}

Since the third argument of the recursive iteration is rest_(columns(a) + 1), and since the number of columns from a value of the first iteration was 2 then rest(3) ends up returning zero columns from the table since the argument being passed in now equals the total number of columns in the table. Therefore, b ends up evaluating to nothing in this iteration.

由于递归迭代的第三个参数是REST_(Columns(A)+1),并且由于第一次迭代的值的列数为2,因此REST(3)最终从表中返回零列,因为现在传入的参数等于表中的总列数。因此,在此迭代中,b的计算结果为零。


Fourth Iteration: Since the number of columns from the resultant third iteration’s a argument + 1 will now evaluate to 4, and since this value is greater than the number of columns in the input table, the b variable will evaluate as an error, and the ['a'] value from the previous iteration will be returned ending the recursive function.

第四次迭代:由于结果第三次迭代的a参数+1的列数现在将计算为4,并且由于该值大于输入表中的列数,因此b变量将计算为错误,并且前一次迭代的[‘a’]值将返回递归函数的末尾。


更多回答

Wow, thanks for this epic response, I am still reading it and trying to process it all, just wanted to thank you for taking the time to explain this, amazing response, thank you!

哇,感谢你这个史诗般的回应,我还在读它,并试图处理它,只是想感谢你花时间解释这一点,令人惊叹的回应,谢谢你!

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