假设我有一个函数f,它接受一个向量v并返回一个新的向量,其元素以某种方式转换。 它通过调用假定向量被排序的函数g来做到这一点。 所以我想要像这样定义f:
f[v_] := Module[{s, r},
s = Sort[v]; (* remember the permutation applied in order to sort v *)
r = g[s];
Unsort[r] (* apply the inverse of that permutation *)
]
“Unsort”的最佳方式是什么?
或者,我们是否真的很想要,并以某种方式工作:
answer = Unsort[g[Sort[v]]];
增加:让我们以玩具为例来具体化。 假设我们想要一个带有向量的函数f,并通过向每个元素添加下一个最小元素(如果有的话)来对其进行转换。 如果我们假设向量是有序的,那么这很容易编写,所以让我们编写一个辅助函数g来做出这样的假设:
g[v_] := v + Prepend[Most@v, 0]
现在我们真正想要的函数f,无论v是否有效,它都能正常工作:
f[v_] := (* remember the order;
sort it;
call g on it;
put it back in the original order;
return it
*)
答案 0 :(得分:6)
一种可能的方法:
mylist = {c, 1, a, b, 2, 4, h, \[Pi]}
g /@ (Sort@mylist)[[Ordering@Ordering@mylist]]
给出
{g [c],g 1,g [a],g [b],g [2],g [4],g [h],g [[Pi]]
即,
(Sort@mylist)[[Ordering@Ordering@mylist]] == mylist
我最初从MathGroup获得了上述内容,[编辑]来自Andrzej Kozlowski的帖子
http://forums.wolfram.com/mathgroup/archive/2007/Jun/msg00920.html
答案 1 :(得分:3)
这是Michael Pilat早先的“排序包装”模式suggested
Clear[g];
g[a_] := If[OrderedQ[a], a^2, Print["Failed"]];
g[{3, 2, 1}]
g[a_] := g[Sort@a][[Ordering@Ordering@a]] /; Not[OrderedQ[a]];
g[{3, 2, 1}]
答案 2 :(得分:2)
感谢TomD和Yaroslav,这可能是最简洁/优雅的方式:
f[v_] := g[Sort@v][[Ordering@Ordering@v]]
感谢Janus,这可能是一种更有效的方式:
f[v_] := With[{o = Ordering@v}, g[v[[o]]][[Ordering@o]]]
请注意,它分为2种而不是3种。
对于后人来说,这是我最初的尝试,虽然我认为没有任何建议可以通过以上方式推荐:
f[v_] := With[{o = Ordering[v]}, Sort[Transpose[{o,g[v[[o]]]}]][[All,-1]]]
为了解释评论中的belisarius,我之所以没有将g作为参数传递是因为我认为g是f的辅助函数。 就像我有一个更容易编写的函数f,如果我可以假设它的参数是一个有序向量。 所以我编写假定的版本,然后执行此包装技巧。