4
$\begingroup$

Given a Dataset:

myDs = {<|"id" -> 5, "name" -> "a", "quantity" -> 8.47|>,
        <|"id" -> 1, "name" -> "b", "quantity" -> 1.22`|>,
        <|"id" -> 2, "name" -> "c", "quantity" -> 9.61|>,
        <|"id" -> 4, "name" -> "d", "quantity" -> 6.56|>,
        <|"id" -> 3, "name" -> "e", "quantity" -> 5.17`|>} // Dataset  

I'm using Select as a query operator in this way:

myDs[Select[#["id"] == 1&], "name"][[1]] // Normal  
(* output: "b" *)  

I now want to pass a list of values (the ids) to Select so that they are tested, but I can't simply map it because of the ampersand right next to where my Map slot would go.
My current solution is having an ad hoc function:

querySelect[dataset_Dataset, testKey_String, testValue_, wantedKey_String]:=
dataset[Select[#[testKey] == testValue &], wantedKey][[1]] // Normal  

querySelect[dataset_Dataset, testKey_String, testValues_List, wantedKey_String]:=
querySelect[dataset, testKey, #, wantedKey] & /@ testValues   

Which does the work:

ids = myDs[All, "id"] // Normal;

querySelect[myDs, "id", ids, "name"]
(* out: {"a", "b", "c", "d", "e"} *)

I wonder, however, if there are ways to pass the values and bypass the clash of slots without resorting to user-defined functions.

$\endgroup$
6
$\begingroup$

You can use Function to proceed

myDs[Select[Or @@ (Function[id, #id == id] /@ {5, 4, 1}) &], "name"]

but there are shorter ways:

myDs[Select[MemberQ[{5, 4, 1}, #id] &], "name"]

myDs[Cases[KeyValuePattern["id" -> (5 | 4 | 1)]], "name"]

myDs[GroupBy[#, Key["id"] -> Key["name"], First] & /* Lookup[Key /@ {5, 4, 1}]]

but what if I have a list of lists that I want to pass instead? [...] I meant a list of lists of values: in this case, different combinations of the ids, so for example {{1, 2, 4, 3}, {2, 4, 3}, {3,2}}?

{{1, 2, 4, 3}, {2, 4, 3}, {3, 2}} /. Normal[
    myDs[GroupBy[#, Key["id"] -> Key["name"], First] &]
]
{{"b", "c", "d", "e"}, {"c", "d", "e"}, {"e", "c"}}
$\endgroup$
  • $\begingroup$ Thank you! This may seem a little redundant, but what if I have a list of lists that I want to pass instead? I see myself struggling again with the exact same problem (probably because I don't have a full grasp of the solution that uses Function). $\endgroup$ – Mumen Raida Jul 25 '16 at 20:13
  • $\begingroup$ @MumenRaida lists of lists of what? $\endgroup$ – Kuba Jul 25 '16 at 20:30
  • $\begingroup$ I'm sorry, I meant a list of lists of values: in this case, different combinations of the ids, so for example {{1, 2, 4, 3}, {2, 4, 3}, {3,2}} $\endgroup$ – Mumen Raida Jul 25 '16 at 20:52
  • $\begingroup$ @MumenRaida {{1, 2, 4, 3}, {2, 4, 3}, {3, 2}} /. Normal@myDs[GroupBy[#, Key["id"] -> Key["name"], First] &] is ok? $\endgroup$ – Kuba Jul 25 '16 at 20:58
  • $\begingroup$ That's perfect! Thank you very much. $\endgroup$ – Mumen Raida Jul 25 '16 at 21:11

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.