Unsort: remembering a permutation and undoing it

后端 未结 3 942
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-06 02:11

Suppose I have a function f that takes a vector v and returns a new vector with the elements transformed in some way. It does that by calling function g that assumes the vec

3条回答
  •  庸人自扰
    2021-01-06 02:36

    Thanks to TomD and Yaroslav, here's probably the most concise/elegant way to do it:

    f[v_] := g[Sort@v][[Ordering@Ordering@v]]
    

    And thanks to Janus, here's a perhaps more efficient way:

    f[v_] := With[{o = Ordering@v}, g[v[[o]]][[Ordering@o]]]
    

    Note that it does 2 sorts instead of 3.

    For posterity, here's my original attempt, though I don't think it has anything to recommend it over the above:

    f[v_] := With[{o = Ordering[v]}, Sort[Transpose[{o,g[v[[o]]]}]][[All,-1]]]
    

    To address belisarius in the comments, the reason I'm not passing g as a parameter is because I'm thinking of g as a helper function for f. It's like I have a function f that would be easier to write if I could assume its argument was a sorted vector. So I write the version that assumes that and then do this wrapper trick.

提交回复
热议问题