4
$\begingroup$

This is probably asked before but I don't know how to begin searching for it.

Some context: I'm using TemporalData objects that share a number of common features but also have distinct characteristics. I use their MetaInformation to catalog these features for future reference. The output of the desired function will be used as the second argument in Rule[Metainformation, #].

I'm trying to accomplish the following: given a list of common keys and values (common:{keys_, values_}) and another list consisting of two elements namely a list of lists of distinct keys and another list of lists of their corresponding distinct values (unique:{allKeys_, allValues_}) I want to produce a list of lists of rules where all lists of rules will contain both the common and the corresponding distinctive features.

An example: Assuming f is the desired function, then

in = {
  { {"a","b","c"}, {1,2,3} },
  { {{"d"}, {"e","f"}, {"g","h","i"}}, {{4}, {5,6}, {7,8,9}} }
 };

f @@ in

is expected to produce out, where out is defined as follows:

out = {
  {"a"->1, "b"->2, "c"->3, "d"->4},
  {"a"->1, "b"->2, "c"->3, "e"->5, "f"->6},
  {"a"->1, "b"->2, "c"->3, "g"->7, "h"->8, "i"->9}
 }

(Please note that the number of elements in the lists of common and the corresponding elements in the lists of unique is expected to be random. I used the example above just for ease of exposition.)

I have developed 3 function versions that seem to do what I want but they all feel a bit clunky; also, I think they are too similar. Furthermore, only the second one is a proper function.

If there are any suggestions on the presented code or-better yet-if there are any other ideas on how to code f, that would be great!

Some f's

  • 1.

    f[common:{keys_, values_}, unique:{allKeys_, allValues_}] := 
      h[Apply[g /* List, common], Thread[Apply[g, unique]]]
    

    and

    {out} === (f[Sequence @@ in] /. h[x__] :> 
     Outer[j /* (Thread[#, g] &), x] /. {j -> Join, g -> Rule /* Thread})
    

    evaluates to

    True
    
  • 2.

    f[common:{keys_, values_}, unique:{allKeys_, allValues_}] := Outer[
      List /* Transpose /* Apply[Rule /* (Apply[Join, #, 1] &) /* Thread], 
        {common}, Transpose[unique], 1]
    

    and

    {out} == f @@ in
    

    evaluates to

    True
    
  • 3.

    f[common:{keys_, values_}, unique:{allKeys_, allValues_}] := 
      Apply[Rule][Thread[g[common, unique]]]
    

    and

    out === (
      ( f @@ in /. g[x_, y_] :> ReleaseHold[
          Distribute[Hold[Join][{x}, y], List]
         ] ) // Thread /* Map[Thread]
     )
    

    evaluates to

    True
    
$\endgroup$
4
+100
$\begingroup$
ClearAll[f1, f2, f3]
f1 = Catenate /@ Thread[MapThread[Thread@*Rule] /@ #, List, {2}] &;

f2 = Join @@@ Thread[MapThread[Thread@*Rule] /@ #, List, {2}] &;

f3 = Association @@@ Thread[MapThread[Thread@*Rule] /@ #, List, {2}] &;



f1 @ in

{{"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4}, {"a" -> 1, "b" -> 2, "c" -> 3, "e" -> 5, "f" -> 6}, {"a" -> 1, "b" -> 2, "c" -> 3, "g" -> 7, "h" -> 8, "i" -> 9}}

Normal[f3 @ in] == f2 @ in == f1 @ in == out

True

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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