我可以使用以下方法为列表中每个元素的第一个组件执行一些操作(在本例中为ToString
):
{ToString@#[[1]], Rest@#}~Flatten~1 & /@ {{1, 2}, {3, 4, 5}}
但是,我有几个问题:
{ToString@#[[1]], Rest@#}~Flatten~1 & /@ {{1,
2}, 2, {3, 4, 5}}
无效。如何使它也工作
这个案例?预期输出为{{"1", 2}, 2, {"3", 4, 5}}
。{{0}, {1, "2"}, {3, "4", 5}, {6, "7", 9, 10}}
/.{#[[1]]->ToString[#[[1]]]}
)进行这种操作?因此,无论效率如何,请列出您可能想到的所有解决方案。非常感谢!
答案 0 :(得分:5)
在我写完之前,我没有意识到这与Leonid的核心功能相同。或许这说明这可能比他相当精细的功能更透明。
lst = {{1, 2}, 2, {3, 4, 5}};
Replace[lst, {a_, b__} :> {ToString@a, b}, 1]
{{"1", 2}, 2, {"3", 4, 5}}
然后可以使用{x:Repeated[_, {4}], a_, b__} :> {x, ToString@a, b}, 1]
作为第五个索引,等等。
答案 1 :(得分:4)
以下功能基本上可以做你想要的:
ClearAll[applyToAll];
applyToAll[f_, list_List, n_Integer] :=
applyToAll[x_ :> f[x], list, n];
applyToAll[rule : (_Rule | _RuleDelayed), list_List, n_Integer] :=
Replace[
list, {left : Repeated[_, {n - 1}], el_, rest___} :>
{left, el /. rule, rest}, {1}];
并且可以接受规则。例如:
In[192]:=
applyToAll[ToString, {{1,2},2,{3,4,5}},1]//InputForm
Out[192]//InputForm= {{"1", 2}, 2, {"3", 4, 5}}
In[193]:= applyToAll[ToString,{{0},{1,2},{3,4,5},{6,7,9,10}},2]//InputForm
Out[193]//InputForm= {{0}, {1, "2"}, {3, "4", 5}, {6, "7", 9, 10}}
In[194]:= applyToAll[x_?OddQ:>ToString[x],{{0},{1,2},{3,4,5},{6,7,9,10}},2]//InputForm
Out[194]//InputForm= {{0}, {1, 2}, {3, 4, 5}, {6, "7", 9, 10}}
答案 2 :(得分:2)
另一种方便的方法可能是将ReplacePart
与RuleDelayed
例如,将每个子列表的第3部分(如果存在)转换为字符串:
ReplacePart[#, 3 :> ToString@#[[3]]] & /@ {{1, 2},
2, {3, 4, 5}, {6, 7, 9, 10}} // InputForm
作为输出:
{{1,2},2,{3,4,“5”},{6,7,“9”,10}}
同样,要将每个子列表的第1部分转换为字符串:
ReplacePart[#, 1 :> ToString@#[[1]]] & /@ {{1, 2},
2, {3, 4, 5}} // InputForm
,并提供:
{{“1”,2},2,{“3”,4,5}}
答案 3 :(得分:1)
从长远来看,我认为这可能是一种更简单的方法,即使它不是你所要求的:
rep[f_, pos_][x_List] := MapAt[f, x, pos]
rep[__][x_] := x
lst = {{1, 2}, 2, {3, 4, 5}};
rep[ToString, 2] /@ lst
{{1, "2"}, 2, {3, "4", 5}}
您可以根据需要在rep
的定义中添加任意模式和条件。