5
$\begingroup$

I use Mathematica 11.0.1 on Windows10, consider the following MWE:

Needs["GeneralUtilities`"];

dsA = {{"id" -> 1,
     "valueA" -> 100,
     "code" -> {
       {"step" -> "navigateTo", "arg" -> "url"},
       {"step" -> "click", "arg" -> "CSS"}}},
    {"id" -> 2,
     "valueA" -> 101,
     "code" -> {
      {"step" -> "navigateTo", "arg" -> "url"},
      {"step" -> "click", "arg" -> "CSS"}
       }}} // ToAssociations //Dataset;

dsB = {{"id" -> 2,
     "valueB" -> 110,
     "code" -> {
       {"step" -> "execute", "arg" -> "JS"},
       {"step" -> "waitForElements", "arg" -> "CSS"}}},
    {"id" -> 3,
     "valueB" -> 111,
     "code" -> {
       {"step" -> "execute", "arg" -> "JS"},
       {"step" -> "waitForElements", "arg" -> "CSS"}}}} // 
   ToAssociations //Dataset;

dsC = ToAssociations[Map[{
      Append[#,
        "code" -> Normal[Join[
           #[["L-code"]],
           #[["R-code"]]
           ]]] // ToAssociations
      } &,
    JoinAcross[dsA, dsB, "id", 
     "KeyCollisionFunction" -> ({"L-" <> #, "R-" <> #} &)]
    ]] // Dataset

Now, the query

dsA[[All, {"valueA"}]]

works as expected, but the query

dsC[[All, {"valueA"}]]

aborts with message:

Message Part::partw,{"valueA"} of ... does not exist.

Clearly, I must have done something wrong. I basically want to select id, valueA, valueB and code ( drop code-L, code-R ) from dsC, how can this be done and why the error message?

Note that the following code is a workaround that works in this MWE but would be rather verbose and impractical in the actual code base:

dsC = Map[{
      "id" -> #[["id"]],
      "valueA" -> #[["valueA"]],
      "valueB" -> #[["valueB"]],
      "code" -> Join[
         #[["L-code"]],
         #[["R-code"]]] // Normal
      } &,
    JoinAcross[dsA // Normal, dsB // Normal, "id",
     "KeyCollisionFunction" -> ({"L-" <> #, "R-" <> #} &)]] // 
   ToAssociations // Dataset

In this case

dsC[[All, {"valueA"}]] 

works OK.

$\endgroup$
5
$\begingroup$

Is this what you are after?

JoinAcross[
    dsA, dsB, "id", "KeyCollisionFunction" -> ({"L-" <> #, "R-" <> #} &)
][
    All
  , Append[#, "code" -> Join[#"L-code", #"R-code"]] & /*  
        KeyTake[{"id", "valueA", "valueB", "code"}]
]
| improve this answer | |
$\endgroup$
  • $\begingroup$ Can anyone explain to me why there isn't some kind of KeyCollisionMergeFunction which automatically creates key -> mergeF[{val1 val2}]? Maybe JoinAcross is an abstract concept from db world and what we have is what people outside expect? $\endgroup$ – Kuba Mar 17 '17 at 12:09
  • $\begingroup$ That's what I am after, yes. KeyTake is new for me. $\endgroup$ – nilo de roock Mar 17 '17 at 12:13
  • 1
    $\begingroup$ @niloderoock #[[{"id",...]]& would probably work too $\endgroup$ – Kuba Mar 17 '17 at 12:15
5
$\begingroup$

If you inspect your dataset with

dsC // Normal

you will notice that it is a list of a list of associations. Thus:

dsC = ToAssociations[
    Map[{Append[#, 
       "code" -> Normal[Join[#[["L-code"]], #[["R-code"]]]]] // 
        ToAssociations} &, 
        JoinAcross[dsA, dsB, "id", 
        "KeyCollisionFunction" -> ({"L-" <> #, "R-" <> #} &)]]] // 
   Flatten // Dataset

And it works fine.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Yes, works indeed. $\endgroup$ – nilo de roock Mar 17 '17 at 12:12

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.