原始问题:
我知道Mathematica有一个内置的地图(f,x),但这个功能是什么样的?我知道你需要查看列表中的每个元素。
任何帮助或建议?
编辑(由Jefromi,Mike的评论拼凑而成):
我正在开发一个程序,需要通过像Map这样的列表,但我不允许使用它。我也不允许使用Table;我需要在没有其他功能帮助的情况下浏览列表。我正在处理一个递归版本,我有一个空列表,但是在列表中包含其中的项目并没有成功。这是我的第一个案例:newMap[#, {}] = {}
(空列表的地图只是一个空列表)
答案 0 :(得分:6)
我发布了一个递归解决方案但后来决定将其删除,因为从评论中这听起来像是一个家庭作业问题,而且我通常是一个教导鱼人。
您正在使用定义newMap[f_, {}] := {}
的递归解决方案。
Mathematica的模式匹配是你的朋友。考虑如何实现newMap[f_, {e_}]
的定义,并从那里newMap[f_, {e_, rest___}]
。
最后一个提示:一旦你可以定义最后一个函数,你实际上并不需要{e_}
的情况。
<强>更新强>:
根据您的评论,这个例子可能会帮助您了解如何应用任意函数:
func[a_, b_] := a[b]
In[4]:= func[Abs, x]
Out[4]= Abs[x]
<强>解强>
由于OP捕获了一条鱼,可以这么说(恭喜!)这里有两个递归解决方案,以满足任何旁观者的好奇心。第一个可能是我认为的“惯用语”Mathematica:
map1[f_, {}] := {}
map1[f_, {e_, rest___}] := {f[e], Sequence@@map1[f,{rest}]}
这种方法不能充分利用模式匹配,这基本上是OP最终的结果:
map2[f_, {}] := {}
map2[f_, lis_] := {f[First[lis]], Sequence@@map2[f, Rest[lis]]}
{f[e], Sequence@@map[f,{rest}]}
部分可以用各种等效方式表达,例如:
Prepend[map[f, {rest}], f[e]]
Join[{f[e]}, map[f, {rest}]
(@Mike使用此方法)Flatten[{{f[e]}, map[f, {rest}]}, 1]
我会让读者继续思考,并思考大多数人的表现影响=)
最后,为了好玩,这是一个程序版本,即使写它让我有点恶心:; - )
map3[f_, lis_] :=
(* copy lis since it is read-only *)
Module[{ret = lis, i},
For[i = 1, i <= Length[lis], i++,
ret[[i]] = f[lis[[i]]]
];
ret
]
答案 1 :(得分:1)
要回答你在评论中提出的问题,Map
中的第一个参数是一个接受单个参数的函数。这可以是纯函数,也可以是只接受单个参数的函数的名称,如
In[1]:=f[x_]:= x + 2
Map[f, {1,2,3}]
Out[1]:={3,4,5}
关于如何用你自己设计的递归函数替换Map
......在Jefromi的例子之后,我不会放弃太多,因为这是作业。但是,您显然需要某种方式对列表的某个部分进行操作,同时保持列表的其余部分对于映射函数的递归部分保持不变。正如他所说,Part
是一个很好的起点,但我会查看它引用的其他一些函数,看看它们是否更有用,例如First
和Rest
。另外,我可以看到Flatten
在哪里有用。最后,您需要一种方法来结束递归,因此学习如何约束模式可能很有用。顺便提一下,这可以用一行或两行完成,具体取决于你是否为地图创建了第二个定义(更简单的方法)。
提示:既然您已经有了最终条件,那么您需要回答三个问题:
有助于考虑流程中的一个步骤,以及在该步骤中您需要完成的任务。