递归 LAMBDA 以通过查找 table 中的特定替代品替换字符
Recursive LAMBDA to replace characters by specific substitutes from a lookup table
目标是遍历字符的行 table 并用它的替代字符替换每个字符。
这个例子中的字符table是={"&","&";"<","<";">",">";"'","'";"""","""}
,或者:
*(旁注:在这种情况下,"&","&"
必须排在列表的最后,否则它将替换之前替换中的其他出现,因为我们是从最后到第。)
公式:
=LAMBDA(XML,Pos,
LET(
Cls,{"&","&";"<","<";">",">";"'","'";"""","""},
Row,IF(ISOMITTED(Pos),ROWS(Cls),Pos),
Crf,INDEX(Cls,Row,1),
Crr,INDEX(Cls,Row,2),
Sub,SUBSTITUTE(XML,Crf,Crr),
IF(Row=0,XML,ENCODEXML(Sub,Row-1))
))
=ENCODEXML("sl < dk & jf")
的预期结果为 sl < dk & jf
我收到 #VALUE!
错误。
- 你需要在递归上有一个出口:
=LAMBDA(XML,Pos,
LET(
Cls,{"&","&";"<","<";">",">";"'","'";"""","""},
Row,IF(ISOMITTED(Pos),ROWS(Cls),Pos),
Crf,INDEX(Cls,Row,1),
Crr,INDEX(Cls,Row,2),
Sub,SUBSTITUTE(XML,Crf,Crr),
IF(Row>1,ENCODEXML(Sub,Row-1),Sub)
))
- 您需要在调用中添加
,
:
=ENCODEXML("sl < dk & jf",)
或者正如@Filcuk 发现的(我刚刚了解到)如果它是可选的,则需要使用 []
声明
即:
=LAMBDA(XML,[Pos],
LET(
Cls,{"&","&";"<","<";">",">";"'","'";"""","""},
Row,IF(ISOMITTED(Pos),ROWS(Cls),Pos),
Crf,INDEX(Cls,Row,1),
Crr,INDEX(Cls,Row,2),
Sub,SUBSTITUTE(XML,Crf,Crr),
IF(Row>1,ENCODEXML(Sub,Row-1),Sub)
))
那么,
就不需要了:
=ENCODEXML("sl < dk & jf")
只是为了补充 Scott 上面的回答;通过名称管理器使用递归 lambda 似乎已经过时(如果没有明确需要命名函数供以后使用)。因为 REDUCE()
本身就是一个递归函数。因此,可以应用以下结构:
=LET(X,<LookupTable>,REDUCE(<InputValue>,INDEX(X,0,1),LAMBDA(a,b,SUBSTITUTE(a,b,VLOOKUP(b,X,<ReturnCol>,0)))))
其中:
<LookupTable>
- 指的是最左边的列包含查找值的矩阵。对于 VLOOKUP()
尤其如此,但是,对于不同的结构,可以开始使用 XLOOKUP()
(以使解决方案更适用);
<InputValue>
- 对需要应用替换的输入字符串的引用;
<ReturnCol>
- 除了第 1 点:当使用 VLOOKUP()
时,需要给出一个引用具有替换值的列的索引;
在 OP 给出的情况下,这将转换为:
=LET(X,{"&","&";"<","<";">",">";"'","'";"""","""},REDUCE("sl < dk & jf",INDEX(X,0,1),LAMBDA(a,b,SUBSTITUTE(a,b,VLOOKUP(b,X,2,0)))))
目标是遍历字符的行 table 并用它的替代字符替换每个字符。
这个例子中的字符table是={"&","&";"<","<";">",">";"'","'";"""","""}
,或者:
*(旁注:在这种情况下,"&","&"
必须排在列表的最后,否则它将替换之前替换中的其他出现,因为我们是从最后到第。)
公式:
=LAMBDA(XML,Pos,
LET(
Cls,{"&","&";"<","<";">",">";"'","'";"""","""},
Row,IF(ISOMITTED(Pos),ROWS(Cls),Pos),
Crf,INDEX(Cls,Row,1),
Crr,INDEX(Cls,Row,2),
Sub,SUBSTITUTE(XML,Crf,Crr),
IF(Row=0,XML,ENCODEXML(Sub,Row-1))
))
=ENCODEXML("sl < dk & jf")
的预期结果为 sl < dk & jf
我收到 #VALUE!
错误。
- 你需要在递归上有一个出口:
=LAMBDA(XML,Pos,
LET(
Cls,{"&","&";"<","<";">",">";"'","'";"""","""},
Row,IF(ISOMITTED(Pos),ROWS(Cls),Pos),
Crf,INDEX(Cls,Row,1),
Crr,INDEX(Cls,Row,2),
Sub,SUBSTITUTE(XML,Crf,Crr),
IF(Row>1,ENCODEXML(Sub,Row-1),Sub)
))
- 您需要在调用中添加
,
:
=ENCODEXML("sl < dk & jf",)
或者正如@Filcuk 发现的(我刚刚了解到)如果它是可选的,则需要使用 []
即:
=LAMBDA(XML,[Pos],
LET(
Cls,{"&","&";"<","<";">",">";"'","'";"""","""},
Row,IF(ISOMITTED(Pos),ROWS(Cls),Pos),
Crf,INDEX(Cls,Row,1),
Crr,INDEX(Cls,Row,2),
Sub,SUBSTITUTE(XML,Crf,Crr),
IF(Row>1,ENCODEXML(Sub,Row-1),Sub)
))
那么,
就不需要了:
=ENCODEXML("sl < dk & jf")
只是为了补充 Scott 上面的回答;通过名称管理器使用递归 lambda 似乎已经过时(如果没有明确需要命名函数供以后使用)。因为 REDUCE()
本身就是一个递归函数。因此,可以应用以下结构:
=LET(X,<LookupTable>,REDUCE(<InputValue>,INDEX(X,0,1),LAMBDA(a,b,SUBSTITUTE(a,b,VLOOKUP(b,X,<ReturnCol>,0)))))
其中:
<LookupTable>
- 指的是最左边的列包含查找值的矩阵。对于VLOOKUP()
尤其如此,但是,对于不同的结构,可以开始使用XLOOKUP()
(以使解决方案更适用);<InputValue>
- 对需要应用替换的输入字符串的引用;<ReturnCol>
- 除了第 1 点:当使用VLOOKUP()
时,需要给出一个引用具有替换值的列的索引;
在 OP 给出的情况下,这将转换为:
=LET(X,{"&","&";"<","<";">",">";"'","'";"""","""},REDUCE("sl < dk & jf",INDEX(X,0,1),LAMBDA(a,b,SUBSTITUTE(a,b,VLOOKUP(b,X,2,0)))))