3
$\begingroup$

This is a new twist of an earlier question about how to get variable names as strings from a function.

I would like to have a function that returns a list of variable names, each being a string, from a list of variables. The goal is to be able to generate a grid that lists the variable name in one column, and the variable values in another, and to iterate this over a list of variables. I have tried:

a = {1, 2, 3, 4, 5};
b = {2, 4, 6, 8};
c = {1, 3, 5, 7};

Clear[varName]
SetAttributes[varName, HoldFirst]
varName[var_] := SymbolName[Unevaluated@var];

{varName[#], Length[#]} & /@ {a, b, c}

which does not yield symbol name. The closest I have come is this (using Length as an example function)

{ToString@#, Length @@ #} & /@ HoldForm /@ Unevaluated@{a, b, c}

{{"a", 5}, {"b", 4}, {"c", 4}}

What I can't figure out is how to define this as a function

func[varlist_]:={ToString@#, Length @@ #} & /@ HoldForm /@ Unevaluated@varlist

func[{a,b,c}]

Desired result: {{"a", 5}, {"b", 4}, {"c", 4}}

Thanks!

$\endgroup$

3 Answers 3

3
$\begingroup$
SetAttributes[fun, {HoldFirst, Listable}]
fun[var_] := {SymbolName[Unevaluated[var]], Length[var]}
fun[{a, b, c}]

{{"a",5},{"b",4},{"c",4}}

$\endgroup$
2
  • $\begingroup$ Now why didn't I think of that? +1 :^) $\endgroup$
    – Mr.Wizard
    Feb 17, 2017 at 2:45
  • $\begingroup$ @Mr.Wizard Well,glad to know I am better a little. :) $\endgroup$
    – yode
    Feb 17, 2017 at 3:32
3
$\begingroup$

I would first define a function that can get just the variable names:

SetAttributes[varNames, HoldAll]
varNames[{varList__}]:=List @@ ToString /@ Unevaluated /@ Hold[varList]

Then, you can use the function:

SetAttributes[func, HoldAll]
func[v_List] := Thread[{varNames[v], Length/@v}]

Example:

a = {1, 2, 3, 4, 5};
b = {2, 4, 6, 8};
c = {1, 3, 5, 7};

func[{a,b,c}]

{{a,5},{b,4},{c,4}}

$\endgroup$
3
$\begingroup$

First of all this might be a simpler approach:

Cases[
  Unevaluated[{a, b, c}],
  var_ :> {ToString @ Unevaluated @ var, Length @ var}
]
{{"a", 5}, {"b", 4}, {"c", 4}}

To make this a function:

Attributes[func] = HoldFirst;

func[x_List] := 
    Cases[
      Unevaluated[x],
      var_ :> {ToString @ Unevaluated @ var, Length @ var}
    ]
$\endgroup$
1
  • $\begingroup$ Elegant and functional, as always!! Thank you. $\endgroup$
    – GraphMan
    Mar 2, 2017 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.