10
$\begingroup$

Is there a way to create a two-way association or a bijection between two lists of equal length? I know I can use AssociationThread twice, flipping the arguments, but how can I create a bijective function which associates each element in one list with an element of another, and vice-versa?

$\endgroup$
2
  • 1
    $\begingroup$ In what way does the solution you mention fall short of what you want? $\endgroup$
    – Alan
    Sep 13, 2016 at 3:21
  • $\begingroup$ @Alan its more clunky: using two variables instead of one. $\endgroup$
    – Matt G
    Sep 13, 2016 at 3:24

4 Answers 4

9
$\begingroup$

A bijective function:

list1 = {1, 2, 3, 4};
list2 = {5, 6, 7, 8};
MapThread[(f[#] = #2; f[#2] = #) &, {list1, list2}]

f[2]
(* Out: 6 *)

And the AssociationThread solution that you mention:

f = <|AssociationThread[list1 -> list2], AssociationThread[list2 -> list1]|>;

f[2]
(* Out: 6 *)
$\endgroup$
2
$\begingroup$
a = {1, 2, 3, 4};
b = {5, 6, 7, 8};

A short variant of C.E.'s answer

f = <|Thread /@ {a -> b, b -> a}|>;

f[2]

6

$\endgroup$
2
$\begingroup$
a = {1, 2, 3, 4};
b = {5, 6, 7, 8};

A short variant of C.E.'s answer

f[lists__List] := Append @@ (AssociationThread @@@ {#, Reverse@#}) &@{lists};

{f[a, b][2], f[a, b][6]}

(*{6, 2}*)
$\endgroup$
0
$\begingroup$

Using PositionIndex with the 'default' argument of Lookup:

a=AssociationThread[list1,list2];

Lookup[a,#,Sequence@@PositionIndex[a][#]]&/@Join[list1,list2]

(* {5,6,7,8,1,2,3,4}  *) 

As a function:

f[lista_,listb_]:=Module[{a=AssociationThread[lista,listb]},
    Lookup[a,#,Sequence@@PositionIndex[a][#]]&]

bij=f[list1,list2];

bij/@Join[list1,list2]

(* {5,6,7,8,1,2,3,4}  *) 

bij[1]

(* 5 *)

bij[5]

(* 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.