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$

1 Answer 1

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$
5
  • $\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$ Jul 25, 2016 at 20:13
  • $\begingroup$ @MumenRaida lists of lists of what? $\endgroup$
    – Kuba
    Jul 25, 2016 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$ Jul 25, 2016 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, 2016 at 20:58
  • $\begingroup$ That's perfect! Thank you very much. $\endgroup$ Jul 25, 2016 at 21:11

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.