11
$\begingroup$

I have two lists of rules:

aa = {1 -> {5, 2}, 3 -> {2, 2}, 4 -> {2, 3}, 5 -> {1, 2}, 6 -> {1, 1},
7 -> {2, 1}, 8 -> {1, 1}};
newVnames = {1 -> "EGW", 2 -> "MA2", 3 -> "HLT", 4 -> "AGF", 
5 -> "WHS", 6 -> "TSC", 7 -> "CO12", 8 -> "FIN"};

List aa has 7 elements, while newVnames has 8 (unbalanced lists). This implies that we need first to drop one irrelevant rule from newVnames which is 2->"MA2" and then replace the remaining elements in newVnames in ONLY to the first elements (before ->) of aa.

For example, {1->"EGW"} in newVnames should be replaced in the first element of the first element in aa to get:

EGW->{5,2}

I tried various versions of:

Table[aa[[i]][[1]] /. newVnames[[i]], {i, Length[aa]}]

But I could not get what I want to. Please advise me a code for this task.

$\endgroup$
4
  • 6
    $\begingroup$ Normal@KeyMap[Association[newVnames]]@Association[aa]? $\endgroup$
    – kglr
    Commented Jan 31, 2023 at 18:58
  • 5
    $\begingroup$ or Normal@KeyMap[ReplaceAll[newVnames]]@Association[aa]? $\endgroup$
    – kglr
    Commented Jan 31, 2023 at 18:59
  • 5
    $\begingroup$ or SubsetMap[ReplaceAll[newVnames], aa, {All, 1}] $\endgroup$
    – kglr
    Commented Jan 31, 2023 at 19:01
  • 5
    $\begingroup$ also SubsetMap[ReplaceAll@newVnames, {All, 1}]@aa $\endgroup$
    – kglr
    Commented Jan 31, 2023 at 19:01

6 Answers 6

11
$\begingroup$
Normal @ KeyMap[Association @ newVnames] @ Association @ aa
Normal @ KeyMap[ReplaceAll @ newVnames] @ Association @ aa
MapAt[ReplaceAll @ newVnames, {All, 1}] @ aa 
SubsetMap[ReplaceAll @ newVnames, {All, 1}] @ aa 

all give

{"EGW" -> {5, 2}, "HLT" -> {2, 2}, "AGF" -> {2, 3}, "WHS" -> {1, 2}, 
"TSC" -> {1, 1}, "CO12" -> {2, 1}, "FIN" -> {1, 1}}

You can also do in-place replacement using ReplaceAll[newVnames] with ApplyTo:

aa[[All, 1]] //= ReplaceAll[newVnames];
aa 
{"EGW" -> {5, 2}, "HLT" -> {2, 2}, "AGF" -> {2, 3}, "WHS" -> {1, 2}, 
"TSC" -> {1, 1}, "CO12" -> {2, 1}, "FIN" -> {1, 1}}
$\endgroup$
13
$\begingroup$
Replace[aa, newVnames,2]

(* {EGW -> {5, 2}, HLT -> {2, 2}, AGF -> {2, 3}, WHS -> {1, 2}, TSC -> {1, 1}, 
    CO12 -> {2, 1}, FIN -> {1, 1}} *)
$\endgroup$
1
  • $\begingroup$ Well now I feel stupid. Very nice. $\endgroup$
    – lericr
    Commented Jan 31, 2023 at 20:44
10
$\begingroup$

Maybe the following can help:

 If[Length[#] != 2, Nothing, #[[2, 2]] -> #[[1, 2]]] & /@ 
 GatherBy[Join[aa, newVnames], Keys]
 (*{"EGW" -> {5, 2}, "HLT" -> {2, 2}, "AGF" -> {2, 3}, "WHS" -> {1, 2}, 
    "TSC" -> {1, 1}, "CO12" -> {2, 1}, "FIN" -> {1, 1}}*)
$\endgroup$
10
$\begingroup$

I particlarly like @kglr's answers in the comments, but I went down the Merge path:

Values[Merge[KeyIntersection[{newVnames, aa}], Apply[Rule]]]
$\endgroup$
10
$\begingroup$

Using Lookup:

Thread[Values@newVnames -> 
   Lookup[aa, Keys@newVnames]] // DeleteMissing

OR

MapThread[Rule, 
 Lookup[KeyIntersection[{newVnames, aa}], #, Nothing] &@
  Keys@newVnames]

Result:

{"EGW" -> {5, 2}, "HLT" -> {2, 2}, "AGF" -> {2, 3}, "WHS" -> {1, 2},
"TSC" -> {1, 1}, "CO12" -> {2, 1}, "FIN" -> {1, 1}}

$\endgroup$
4
$\begingroup$
list = 
  {1 -> {5, 2}, 3 -> {2, 2}, 4 -> {2, 3}, 5 -> {1, 2}, 
   6 -> {1, 1}, 7 -> {2, 1}, 8 -> {1, 1}};

names = 
  {1 -> "EGW", 2 -> "MA2", 3 -> "HLT", 4 -> "AGF", 
   5 -> "WHS", 6 -> "TSC", 7 -> "CO12", 8 -> "FIN"};

Using ReplaceAt (new in 13.1)

ReplaceAt[list, names, {All, 1}]

{"EGW" -> {5, 2}, "HLT" -> {2, 2}, "AGF" -> {2, 3}, "WHS" -> {1, 2},
"TSC" -> {1, 1}, "CO12" -> {2, 1}, "FIN" -> {1, 1}}

$\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.