What is the fastest way of combining elements of lists in rules?
L1 = {{a, b}, {c, d}};
L2 = {{e, f}, {g, h}};
L1r = ArrayReshape[L1, {Times @@ Most[#], Last[#]}] &[Dimensions[L1]];
L2r = ArrayReshape[L2, {Times @@ Most[#], Last[#]}] &[Dimensions[L2]];
new = Transpose[Tuples[{L1r, L2r}], {1, 3, 2}];
new[[All, All, 0]] = Rule;
new
{{a -> e, b -> f}, {a -> g, b -> h}, {c -> e, d -> f}, {c -> g, d -> h}}
One straightforward way is with AssociationThread
.
keys = {{a, b}, {c, d}}
values = {{e, f}, {g, h}}
AssociationThread @@@ Tuples[{keys, values}]
(* {<|a -> e, b -> f|>, <|a -> g, b -> h|>,
<|c -> e, d -> f|>, <|c -> g, d -> h|>} *)
And for the second example:
keys = {{a, b}}
values = {{e, f}, {g, h}}
AssociationThread @@@ Tuples[{keys, values}]
(* {<|a -> d|>, <|a -> f|>, <|b -> d|>, <|b -> f|>} *)
Of course, you end up with a list of Association
s, but is that such a bad thing? You can always turn it into a list with Normal
.
As for the second example, it clearly doesn't meet your "lists need not be of the same dimensions" specification. You can either take the one liner and use it on keys = {{a, b}}
instead of {a, b}
, or you can use this longer function, but get the functionality you're after:
listtorules[list1_, values_] :=
Block[{keys = If[Depth[list1] == 2, {list1}, list1]},
Normal[AssociationThread @@@ Tuples[{keys, values}]]
]
Then
listtorules[{a, b}, {{c, d}, {e, f}}]
listtorules[{{a, b}}, {{c, d}, {e, f}}]
both produce
{{a -> c, b -> d}, {a -> e, b -> f}}
Use Outer
:
lst01 = {{a, b}, {c, d}}
lst02 = {{e, f}, {g, h}}
Outer[Thread@*Rule, lst01, lst02, 1]
You'll have to use {{a,b}}
instead of {a,b}
for your second case. And if you really need not have a matrix of results, you can Catenate
the results of the above (but of course that has a cost).