# MapIndexed on a table of SparseArray structures produces different output in Mathematica 12 and 14.0

Here is a snippet I use to dynamically define a bunch of functions f[i][x_]:

Clear[f];
tabrhs = {SparseArray[{1, 1} -> Sin[x]], SparseArray[{1, 1} -> Cos[x]]};
MapIndexed[(f[First[#2]][x_] := #1) &, tabrhs];


In Mathematica 12, this produces the desired output:

f[1][z] (* SparseArray[{1,1} -> Sin[z]] *)
f[2][z] (* SparseArray[{1,1} -> Cos[z]] *)


In Mathematica 14.0, this produces instead:

f[1][z] (* SparseArray[{1,1} -> Sin[x]] *)
f[2][z] (* SparseArray[{1,1} -> Cos[x]] *) (* notice the 'x' instead of 'z' *)


Note that if I do not use SparseArray structures and instead use the simpler:

Clear[f];
tabrhs = {Sin[x], Cos[x]};
MapIndexed[(f[First[#2]][x_] := #1) &, tabrhs];


The result is consistent in both versions:

f[1][z] (* Sin[z] *)
f[2][z] (* Cos[z] *)


I do care for the SparseArray structure, though. Any idea?

Clear[f];
tabrhs={SparseArray[{1,1}->Sin[x]],SparseArray[{1,1}->Cos[x]]};
MapIndexed[(f[First[#2]][t_]:=SparseArray[ArrayRules[#1]/.x->t])&,tabrhs];
f[1][y]//Normal


{{Sin[y]}}

Update:

Clear[f];
tabrhs={SparseArray[{1,1}->Sin[x]],SparseArray[{1,1}->Cos[x]]};
MapIndexed[(f[First[#2]]=SparseArray@*(Function@@{x,ArrayRules@#1}))&,tabrhs];
f[1][y] // Normal


{{Sin[y]}}

Update 2:

Clear[f];
tabrhs={SparseArray[{1,1}->Sin[x]],SparseArray[{_,_}->0,{1,1}]};
MapIndexed[(f[First[#2]]=SparseArray@@#&@*(Function@@{x,{ArrayRules@#1,Dimensions@#1}}))&,tabrhs];
f[1][y]//Normal
f[2][y]//Normal


{{Sin[y]}}

{{0}}

• That works. Follow up: is there a way to make that work with a Set (=) instead of SetDelayed (:=) ? Feb 21 at 21:42
• Also, I'm actually not a fan of the replace rule, as this does not work out of the box in an external package where the t would be interpreted as package'Private't, and not amenable to patterns. Feb 21 at 22:13
• @jrekier Updated.
– Karl
Feb 22 at 1:04
• Yup, that works. Thanks! Feb 22 at 1:32
• @jrekier Updated 2.
– Karl
Feb 22 at 23:32