Renaming and indexing list of rules

I have a list of rules that represents a list of parameters to be applied to a circuit model (Wolfram SystemModeler model):

sk = {
{R1 -> 10080., R2 -> 10080., C1 -> 1.*10^-7, C2 -> 9.8419*10^-8},
{R1 -> 10820., R2 -> 4984.51, R3 -> 10000., R4 -> 10000., C1 -> 1.*10^-7,
C2 -> 1.85417*10^-7},
{R1 -> 12600., R2 -> 12600., C1 -> 1.*10^-7, C2 -> 6.29882*10^-8},
{R1 -> 16420., R2 -> 16420., C1 -> 1.*10^-7, C2 -> 3.70897*10^-8},
{R1 -> 26120., R2 -> 26120., C1 -> 1.*10^-7, C2 -> 1.46573*10^-8},
{R1 -> 76600., R2 -> 1283.61, R3 -> 10000., R4 -> 10000., C1 -> 1.*10^-7,
C2 -> 1.01704*10^-7}};


Before I can apply these values to the model parameters I have to rename them. The list above consists of six lists - four lists of four rules and two lists of six rules. Those that have 4 rules should be named "sallenKeyUnityGain" and those that have 6 rules should be named "sallenKey". This is what I have so far:

Table[If[Length[sk[[i]]] > 4, cirname = "sallenKey", cirname = "sallenKeyUnityGain"];
(cirname <> ToString[i] <> "." <> ToString[sk[[i]][[All, 1]][[j]]]) -> sk[[i]][[All, 2]][[j]]
, {i, Length[sk]}, {j, Length[sk[[i]]]}]


And this is the output:

{{"sallenKeyUnityGain1.R1" -> 10080., "sallenKeyUnityGain1.R2" -> 10080.,
"sallenKeyUnityGain1.C1" -> 1.*10^-7, "sallenKeyUnityGain1.C2" -> 9.8419*10^-8},
{"sallenKey2.R1" -> 10820., "sallenKey2.R2" -> 4984.51, "sallenKey2.R3" -> 10000.,
"sallenKey2.R4" -> 10000., "sallenKey2.C1" -> 1.*10^-7,
"sallenKey2.C2" -> 1.85417*10^-7},
{"sallenKeyUnityGain3.R1" -> 12600., "sallenKeyUnityGain3.R2" -> 12600.,
"sallenKeyUnityGain3.C1" -> 1.*10^-7, "sallenKeyUnityGain3.C2" -> 6.29882*10^-8},
{"sallenKeyUnityGain4.R1" -> 16420., "sallenKeyUnityGain4.R2" -> 16420.,
"sallenKeyUnityGain4.C1" -> 1.*10^-7, "sallenKeyUnityGain4.C2" -> 3.70897*10^-8},
{"sallenKeyUnityGain5.R1" -> 26120., "sallenKeyUnityGain5.R2" -> 26120.,
"sallenKeyUnityGain5.C1" -> 1.*10^-7, "sallenKeyUnityGain5.C2" -> 1.46573*10^-8},
{"sallenKey6.R1" -> 76600., "sallenKey6.R2" -> 1283.61, "sallenKey6.R3" -> 10000.,
"sallenKey6.R4" -> 10000., "sallenKey6.C1" -> 1.*10^-7,
"sallenKey6.C2" -> 1.01704*10^-7}}


This would work fine if all were sallenKey or if all were sallenKeyUnityGain. However, I would like the output to look like this:

 {{"sallenKeyUnityGain1.R1" -> 10080., "sallenKeyUnityGain1.R2" -> 10080.,
"sallenKeyUnityGain1.C1" -> 1.*10^-7, "sallenKeyUnityGain1.C2" -> 9.8419*10^-8},
{"sallenKey1.R1" -> 10820., "sallenKey1.R2" -> 4984.51, "sallenKey1.R3" -> 10000.,
"sallenKey1.R4" -> 10000., "sallenKey1.C1" -> 1.*10^-7,
"sallenKey1.C2" -> 1.85417*10^-7},
{"sallenKeyUnityGain2.R1" -> 12600., "sallenKeyUnityGain2.R2" -> 12600.,
"sallenKeyUnityGain2.C1" -> 1.*10^-7, "sallenKeyUnityGain2.C2" -> 6.29882*10^-8},
{"sallenKeyUnityGain3.R1" -> 16420., "sallenKeyUnityGain3.R2" -> 16420.,
"sallenKeyUnityGain3.C1" -> 1.*10^-7, "sallenKeyUnityGain3.C2" -> 3.70897*10^-8},
{"sallenKeyUnityGain4.R1" -> 26120., "sallenKeyUnityGain4.R2" -> 26120.,
"sallenKeyUnityGain4.C1" -> 1.*10^-7, "sallenKeyUnityGain4.C2" -> 1.46573*10^-8},
{"sallenKey2.R1" -> 76600., "sallenKey2.R2" -> 1283.61, "sallenKey2.R3" -> 10000.,
"sallenKey2.R4" -> 10000., "sallenKey2.C1" -> 1.*10^-7,
"sallenKey2.C2" -> 1.01704*10^-7}}


In other words, if I have 4 apples and 2 oranges, instead of having:
apple1, orange2, apple3, apple4, apple5, orange6, I would like:
apple1, orange1, apple2, apple3, apple4, orange2. How would I do this?
Thank you
Tatjana

Here is a solution :

myFormat[ruleList_, {type_, counter_}] :=
MapAt[type <> ToString[counter] <> "." <> ToString[#] &, #, 1] & /@ ruleList

(* example : myFormat[{R1->1,R2->2}, {"sallenKey",5}] gives : *)
(*           {"sallenKey5.R1"->1, "sallenKey5.R2"->2}         *)

sallenKeyCounter = 0;
sallenKeyUnityGainCounter = 0;
res = myFormat[#, If[
Length[#] <= 4,
{"sallenKeyUnityGain", sallenKeyUnityGainCounter = sallenKeyUnityGainCounter + 1},
{"sallenKey", sallenKeyCounter = sallenKeyCounter + 1}
]] & /@ sk  ;


myFormat is a auxiliary formatting function which is applied to each list of rules completed with the type/number of the item.

res // Grid


• It would be shorter to use e.g. ++sallenKeyCounter – Mr.Wizard May 31 '13 at 13:27
• Thank you for the answer, andre. I implemented your solution using Mr.Wizard's suggestion for the counters. I have not used Map, MapAt or pure functions before and your answer also helped me gain better understanding of those function. – Tatjana Jun 1 '13 at 9:22

This version implements a pair of counters, a & b, while retaining much of the original code :-

a = b = 0;
Table[
If[Length[sk[[i]]] > 4,

cirname = "sallenKey";
(cirname <> ToString[If[a + b != i, ++a, a]] <> "." <>
ToString[sk[[i]][[All, 1]][[j]]]) -> sk[[i]][[All, 2]][[j]],

cirname = "sallenKeyUnityGain";
(cirname <> ToString[If[a + b != i, ++b, b]] <> "." <>
ToString[sk[[i]][[All, 1]][[j]]]) -> sk[[i]][[All, 2]][[j]]

], {i, Length[sk]}, {j, Length[sk[[i]]]}]


Here's a version where the counting is done by structuring the data with GatherBy and using MapIndexed.

lengthToNames = {6 -> "sallenKey", 4 -> "sallenKeyUnityGain"};
gatheredSk = GatherBy[sk, Length];
positionToNames = MapIndexed[
With[{basename = Length[#[[1]]] /. lengthToNames}, {First[#2],
index_, ___} :> basename <> ToString[index]] &, gatheredSk];
rewrite[rule_, name_] := ReplacePart[rule, 1 -> name <> "." <> ToString[First@rule]];

Flatten[
MapIndexed[# /. rule_Rule :> rewrite[rule, #2 /. positionToNames] &, gatheredSk, {3}],
1]


The key is to write a rule that maps positions in gatheredSk to base names.

positionToNames

{{1, index$_, ___} :> "sallenKeyUnityGain" <> ToString[index$],
{2, index$_, ___} :> "sallenKey" <> ToString[index$]}


In this case, it's just as easy to do it by hand. :) Except above the rule was constructed without assuming the order of elements in sk. (Given the problem of getting the numbering right, we probably could have assumed length 4 will always be in position 1, etc.)