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$ Commented Feb 17, 2017 at 2:45
  • $\begingroup$ @Mr.Wizard Well,glad to know I am better a little. :) $\endgroup$ Commented 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$ Commented Mar 2, 2017 at 15:25

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.