0
$\begingroup$

The For expression below initializes downvalues of a variable a from the values in a list list:

Module[
 {   a
   , list = {3, 1, 4}
 }
 , For[i = 1, i <= Length[list], i++, a[i] = list[[i]]]
 ; a[3]
]
(* 4 *)

Is there a simpler way to implement such an assignment? In particular, I'm looking for a way that does not explicitly iterate over the list.


The naive attempt below fails, but at least shows the sort of expression I'm hoping to find:

Module[
 {   a
   , list = {3, 1, 4}
 }
 , Array[a, Length[list]] = list
 ; a[3]
]
(* a$941099[3] *)
$\endgroup$
  • 2
    $\begingroup$ I think the term you are looking for is DownValues instead of "Array". The Array function just creates lists and is in no way connected to something like someArrayName[someIndex] $\endgroup$ – Sascha Jun 5 '16 at 14:30
  • 3
    $\begingroup$ in mathematica an array is a sub-type of a list. Essentially a list that is not ragged. reference.wolfram.com/language/ref/ArrayQ.html $\endgroup$ – george2079 Jun 5 '16 at 15:13
  • 5
    $\begingroup$ note while there may be some reason to do this, in general if you have a list-like thing you should actually use a list. If you use downvalues to hold your list you give up all the rich functionality of mathematica list operations. $\endgroup$ – george2079 Jun 5 '16 at 15:29
  • $\begingroup$ I second george's opinion on staying away from "indexed variables" i.e. DownValues. You loose all that higher-order-function-goodness e.g. Map, Fold and Select. If you really need some kind of readily available "index" additional to your data have a look at Association $\endgroup$ – Sascha Jun 5 '16 at 15:35
  • $\begingroup$ I remember reading, a long, long, long time ago (probably in the very first "Mathematica book"), that in Mathematica, expressions of the form a[i] (single brackets!) were used to represent subscripted variables, as found in standard mathematical notation, i.e. $a_i$. Maybe this is no longer "good Mathematica", but I think it was "the official line" at some point. $\endgroup$ – kjo Jun 5 '16 at 17:20
3
$\begingroup$

Set has the HoldFirst attribute. You need to use Evaluate if you want to do this the way you suggest in your question:

Module[{array, list = {3, 1, 4}},
 Evaluate[Array[array, Length[list]]] = list;
 {array[1], array[2], array[3]}
 ]
(* Out: {3, 1, 4} *)
$\endgroup$
5
$\begingroup$

If I understand your question correctly you want to transform a list e.g. {a,b,c,d} into DownValues of a Symbol with some name e.g. array1. Sometimes this is called an indexed variable (although I think this term is misleading). The following function does just that:

toDownvalues[name_, list_] := MapIndexed[(name[First@#2] = #1) &, list]

ClearAll@array1
toDownvalues[array1, {a, b, c, d}]

Table[array1[i], {i, 1, 4}]
(* {a, b, c, d} *)
$\endgroup$
  • $\begingroup$ Or use array1 /@ Range[4] instead of the Table construct. $\endgroup$ – Bob Hanlon Jun 5 '16 at 15:40
  • 2
    $\begingroup$ @Bob Hanlon, the Table is just there to show that indeed we attached the entries from the list to the Symbol array1 via DownValues. I though that using Table is maybe clearer to the OP because it explicitly uses an index. $\endgroup$ – Sascha Jun 5 '16 at 15:42
2
$\begingroup$

If you are looking for a solution that doesn't iterate over a list, you may be interested by what is called "memoization". The target of memoization is not to assign DownValues to a symbol as you ask. Memoization is a optimization for speed. Assignment of Dowvalues to a symbol is a "side effect" (in all meanings of the term), which is not recommended, but here, that may correspond to your need.

The idea of Memoization is that your array is built more and more each time you call array[index] whith a new index :

Here is the intialisation :

list = {3, 1, 4, 8};
array[i_] := (array[i] = list[[i]])

Definition[array]

enter image description here

The array definition is no more than array[i]=list[i]. This is a parasitic term that may annoy you, depending of your application.

Then if you call array[index] with say, index=1, then the DownValue 3 is added to the definiton of array (array[1]=3) :

array[1]
Definition[array]

enter image description here

and so on ...

array[2]
Definition[array]

enter image description here

Of course, if you want to load the entire array in one time at the beginning, you need to do something similar to a iteration, for example :

array /@ Range[Length[list]]
Definition[array]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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