提问人:Leo 提问时间:10/25/2023 更新时间:10/25/2023 访问量:99
如何在Excel中构建由1D动态数组参数化的2D动态数组
How to build a 2D dynamic array parameterised by a 1D dynamic array in Excel
问:
有没有办法通过在Office 365 Excel中将多个动态数组连接在类似for的循环中创建动态数组?
这是一个 MWE(我的实际列比仅仅使用 .randarray
...并作为文本:
index: =SEQUENCE(,5)
desired: =RANDARRAY(3,5, B1#,B1#+1,TRUE)
workaround: =RANDARRAY(3,,B1,B1+1,TRUE)
attempt 1 (hstack): =HSTACK(RANDARRAY(3,,B1#,B1#+1,TRUE))
attempt 2 (bycol): =BYCOL(B$1#,LAMBDA(m,RANDARRAY(3,1,m,m+1,TRUE)))
我确实注意到(见屏幕截图)存在“嵌套数组”错误,这似乎很重要。我将不胜感激任何反馈、示例或澄清,即使答案是“2023 年不可能”。
答:
RANDARRAY
应用于重复行
重复行
- 这将“重复”行次数,导致(想象复制到)。
3
d
B1:F1
B2:F4
- 然后它使用 和 与函数。
d
d+1
RANDARRAY
=LET(data,B1#,rows,3,increment,1,
d,IF(SEQUENCE(rows),data),
RANDARRAY(COLUMNS(d),rows,d,d+increment,1))
MAKEARRAY(类似于 DjC 在您的评论中的建议)
=LET(data,B1#,rows,3,increment,1,
MAKEARRAY(rows,COLUMNS(data),LAMBDA(r,c,
LET(num,INDEX(data,c),
RANDBETWEEN(num,num+increment)))))
评论
只是为了好玩,这里有一个解决方案,它通过使用定点组合器(p.s.我在reddit上偶然发现了这种方法):LAMBDA()
LET()
=LET(
F, LAMBDA(X,a,b,c,[val],[num],
LET(
d, RANDARRAY(, COLUMNS(a), a, a+b, TRUE),
v, IF(ISOMITTED(val), d, VSTACK(val, d)),
n, IF(ISOMITTED(num), 1, num),
IF(n<c, X(X, a, b, c, v, n+1), v))),
F(F, B1#, 1, 3))
需要明确的是,使用此方法在名称管理器中没有定义任何自定义函数。上述公式可以直接输入到任何单元格中。
结果:
解释:
通常,为了创建递归 lambda 函数,需要在名称管理器中定义它。例如,您可以使用以下公式定义名称:RANDMULT
=LAMBDA(array,increment,rows,[initial_value],[start],
LET(
d, RANDARRAY(, COLUMNS(array), array, array+increment, TRUE),
v, IF(ISOMITTED(initial_value), d, VSTACK(initial_value, d)),
n, IF(ISOMITTED(start), 1, start),
IF(n<rows, RANDMULT(array, increment, rows, v, n+1), v)))
如您所见,如果未满足退出函数的条件,函数将再次调用自身。可选的 [initial_value] 和 [start] 参数是我们传递每次迭代结果的地方,直到迭代次数等于 rows 参数中指定的次数。这与 VBA 中的“For Next”循环基本相同。然后,该公式可以在任何单元格中使用。RANDMULT()
RANDMULT()
=RANDMULT(B1#, 1, 3)
不幸的是,如果我们尝试直接在名称管理器中(而不是在名称管理器中)将相同的递归 lambda 函数定义为名称,它将返回错误。由于函数的约束,名称不能在自己的定义中按名称来指代自己......必须先完全定义它,然后才能使用。这就是定点运算器逻辑的用武之地。LET()
#NAME?
LET()
回到上面的第一个公式,当函数被定义时,它不是在自己的定义中再次调用自身,而是调用函数,该函数作为第一个参数传递给。完全定义函数后,将函数传递给自身以创建递归来使用它。F()
X()
F()
F()
无论如何,我意识到这不是解决这个特定问题的最有效解决方案。我只是觉得这很有趣。干杯!:-)
评论
=MAKEARRAY(3, 5, LAMBDA(r,c, RANDBETWEEN(c, c+1)))
INDEX()
MAKEARRAY()
=MAKEARRAY(3, COLUMNS(B1#), LAMBDA(r,c, RANDBETWEEN(INDEX(B1#,c), INDEX(B1#,c)+1)))
desired
workaround
makearray