3
$\begingroup$

I have list of associations like this:

er={<|A->{d11,{"1b1","2b1","3a1"}},B->{d12,{"1a1","2a1","3b1"}},C->{d13,{"1c1","2c1","3c1"}}|>,
<|A->{d21,{"1b2","2b2","3a2"}},B->{d22,{"1a2","2a2","3b2"}},C->{d23,{"1c2","2c2","3c2"}}|>,
<|A->{d31,{"1b3","2b3","3a3"}},B->{d32,{"1a3","2a3","3b3"}},C->{d33,{"1c3","2c3","3c3"}}|>,
<|A->{d41,{"1a4","2a4","3a4"}},B->{d42,{"1b4","2b4","3b4"}},C->{d43,{"1c4","2c4","3c4"}}|>,
<|A->{d51,{"1a5","2a5","3a5"}},B->{d52,{"1b5","2b5","3b5"}},C->{d53,{"1c5","2c5","3c5"}}|>}

I want to swap data between rules A and B and to only on [[2]][[;; 2]]their parts/levels, eg. in A "1b1","2b1" should be "1a1","2a1", and in B "1a1", "2a1" should be "1b1","2b1",...and the same procedure for only next two associations, 3 in total). So, the resulting, corrected list of associations would be:

ok={<|A->{d11,{"1a1","2a1","3a1"}},B->{d12,{"1b1","2b1","3b1"}},C->{d13,{"1c1","2c1","3c1"}}|>,
<|A->{d21,{"1a2","2a2","3a2"}},B->{d22,{"1b2","2b2","3b2"}},C->{d23,{"1c2","2c2","3c2"}}|>,
<|A->{d31,{"1a3","2a3","3a3"}},B->{d32,{"1b3","2b3","3b3"}},C->{d33,{"1c3","2c3","3c3"}}|>,
<|A->{d41,{"1a4","2a4","3a4"}},B->{d42,{"1b4","2b4","3b4"}},C->{d43,{"1c4","2c4","3c4"}}|>,
<|A->{d51,{"1a5","2a5","3a5"}},B->{d52,{"1b5","2b5","3b5"}},C->{d53,{"1c5","2c5","3c5"}}|>}

Please help with composing procedure to rearrange wrong to correct associations.

EDIT: none of the values are fixed and are not known in advance, they are arbitrary numbers. as, bs and cs are used only for exposure and to avoid mess. Only keys (A, B C) are fixed and known in advance.

$\endgroup$
1
  • 1
    $\begingroup$ You should avoid symbols as key names, and even more capitalized symbols as e.g. C is a built-in symbol. $\endgroup$
    – Kuba
    Commented Feb 28, 2018 at 8:02

4 Answers 4

1
$\begingroup$
Association @* KeyValueMap[
  # -> (
    #2 /. s_String :> StringReplace[s, LetterCharacter :> ToLowerCase[ToString[#]]]
  ) &
] /@ er

enter image description here

$\endgroup$
4
  • $\begingroup$ this is character replacement, but I want value swapping, because contents of values have NO ties with its keys. eg this {<|A->{d11,{"1yy1","2yy1","3xx1"}}, B->{d12,{"1xx1","2xx1","3yy1"}}, C->{d13,{"1zz1","2zz1","3zz1"}}|>, <|A->{d21,{"1yy2","2yy2","3xx2"}}, B->{d22,{"1xx2","2xx2","3yy2"}}, C->{d23,{"1zz2","2zz2","3zz2"}}|>, <|A->{d41,{"1xx3","2xx3","3xx3"}}, B->{d42,{"1yy3","2yy3","3yy3"}}, C->{d43,{"1zz3","2zz3","3zz3"}}|>, <|A->{d51,{"1xx4","2xx4","3xx4"}}, B->{d52,{"1yy4","2yy4","3yy4"}}, C->{d53,{"1zz4","2zy4","3zz4"}}|>} $\endgroup$
    – Dragutin
    Commented Feb 28, 2018 at 8:44
  • $\begingroup$ @Dragutin if there are no ties with A|B|C, how do you know which is swapped and which correct? My answer fits your question, if you have a different question, make sure you explained the problem well. $\endgroup$
    – Kuba
    Commented Feb 28, 2018 at 9:53
  • $\begingroup$ swapping is only in first THREE (I determine this number) associations, between A and B keys, on [[2]][[{1,2}]]. so "1yy1","2yy1" swaps with "1xx1","2xx1". All other remain the same. $\endgroup$
    – Dragutin
    Commented Feb 28, 2018 at 10:27
  • $\begingroup$ @Dragutin You said "as we can see first 3 associations" and then "none of the values are fixed and are not known in advanced". Your question is not clear, please put some effort and edit it with a clear description what is allowed to happen what not, what part of the structure will not change and what can contain arbitrary expressions. Unless I'm mistaken you are now wasting our time. $\endgroup$
    – Kuba
    Commented Feb 28, 2018 at 10:31
0
$\begingroup$

Not the most elegant, but I believe this will do what you want:

Table[
 <|A -> {(A /. er[[i]])[[1]], 
    StringReplace[(A /. er[[i]])[[2]], "b" | "c" -> "a"]},
  B -> {(B /. er[[i]])[[1]], 
    StringReplace[(B /. er[[i]])[[2]], "a" | "c" -> "b"]},
  C -> {(C /. er[[i]])[[1]], 
    StringReplace[(C /. er[[i]])[[2]], "b" | "a" -> "c"]}|>, 
 {i, Length[er]}]

{<|A -> {d11, {"1a1", "2a1", "3a1"}}, 
  B -> {d12, {"1b1", "2b1", "3b1"}}, 
  C -> {d13, {"1c1", "2c1", "3c1"}}|>, <|A -> {d21, {"1a2", "2a2", 
     "3a2"}}, B -> {d22, {"1b2", "2b2", "3b2"}}, 
  C -> {d23, {"1c2", "2c2", "3c2"}}|>, <|A -> {d31, {"1a3", "2a3", 
     "3a3"}}, B -> {d32, {"1b3", "2b3", "3b3"}}, 
  C -> {d33, {"1c3", "2c3", "3c3"}}|>, <|A -> {d41, {"1a4", "2a4", 
     "3a4"}}, B -> {d42, {"1b4", "2b4", "3b4"}}, 
  C -> {d43, {"1c4", "2c4", "3c4"}}|>, <|A -> {d51, {"1a5", "2a5", 
     "3a5"}}, B -> {d52, {"1b5", "2b5", "3b5"}}, 
  C -> {d53, {"1c5", "2c5", "3c5"}}|>}
$\endgroup$
1
  • $\begingroup$ good idea but in my dataset none of the values are fixed and are not known in advanced, they are arbitrary numbers. Only keys (A, B C) are fixed and known in advance. $\endgroup$
    – Dragutin
    Commented Feb 28, 2018 at 7:57
0
$\begingroup$
ok2 = er;
ok2[[;;3]] = ReplaceAll[er[[;;3]], Association[A -> {a_, b_ }, B -> {c_, d_}, rest___] :>
  Association[A -> {a, Append[Most@d, Last@b]}, B-> {c, Append[Most@b, Last@d]}, rest]];
ok2 == ok

True

$\endgroup$
0
$\begingroup$

Thanks for idea. I finally find the solution.

((Association @*({
Keys[#][[1]]->{#[A][[1]],#[B][[2]][[;;2]]~Join~#[A][[2]][[{3}]]},
Keys[#][[2]]->{#[B][[1]],#[A][[2]][[;;2]]~Join~#[B][[2]][[{3}]]},
Keys[#][[3]]->{#[C][[1]],#[C][[2]]}}&)/@#[[;;3]])~Join~#[[4;;]])&@er
$\endgroup$

Your Answer

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

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