Skip to main content

function construction - How to directly/conveniently use variable names as filenames?


Purpose


To use variable name as file name conveniently.


Code


Special thanks to @J.M.'s tips!


Remove@"Global`*"
p = Plot[#, {x, 0, 1}] & /@ {x, 1/x};

SetAttributes[g, HoldAll]
g[p_] := Export[ToString@Unevaluated@p <> ".png", p]


(* Few images: *)
{g@p[[1]], g@p[[2]]}

(* Many images: *)
g /@ Hold @@
Table["p[[" <> ToString@i <> "]]", {i, Length@p}] //
ToString // ToExpression // ReleaseHold

Question



I'm not satisfied with this two lines in the last section of the above code:


    Table["p[[" <> ToString@i <> "]]", {i, Length@p}] //
ToString // ToExpression

I believe there are smarter ways to implement that, please teach me, thanks!



Answer



Maybe something in this line might do:


SetAttributes[ g, HoldFirst ];
g[ sym_ ] := With[
{

baseFileName = SymbolName @ Unevaluated @ sym,
ext = ".png"
},
Switch[ sym,
{ __Graphics },
Range@Length@sym // Scan[ Export[ baseFileName <> ToString @# <> ext, sym[[#]] ] & ],
_Graphics, Export[ baseFileName <> ext, sym ]
]
]


With a single plot this will then be immediately exported, while with a list of plots (e.g. Graphics), the symbol's name will be given an additional counter (e.g. p1.png).


SetDirectory @ NotebookDirectory[];
g[p]
(* will write p1.png and p2.png *)

Comments