5

Is there a neat way of looking up the key of a dictionary by an atom value if that atom is inside a value list ?

Assumption: The value lists of the dictionary have each unique elements

Example:

d:`tech`fin!(`aapl`msft;`gs`jpm) / would like to get key `fin by looking up `jpm
d?`gs`jpm / returns `fin as expected
d?`jpm    / this doesn't work unfortunately
$[`jpm in d`fin;`fin;`tech] / this is the only way I can come up with

The last option does not scale well with the number of keys

Thanks!

Scott
  • 324
  • 1
  • 9
tenticon
  • 2,639
  • 4
  • 32
  • 76

4 Answers4

9

You can take advantage of how where operates with dictionaries, and use in :

where `jpm in/:d
,`fin

Note this will return a list, so you might need to do first on the output if you want to replicate what you have above.

Ryan McCarron
  • 889
  • 4
  • 10
4

Why are you making this difficult on yourself? Use a table!

q)t:([] c:`tech`tech`fin`fin; sym:`aapl`msfw`gs`jpm)
q)first exec c from t where sym=`jpm

You can of course do what you're asking:

first where `jpm in'd

but this doesn't extend well to vectors while the table-approach does!

q)exec c from t where sym in `jpm`gs
geocar
  • 9,085
  • 1
  • 29
  • 37
2

I think you can take advantage of the value & key keywords to find what you're after:

q)key[d]where any value[d]in `jpm
,`fin

Hope that helps!

Jemma

Jemma Borland
  • 390
  • 1
  • 7
  • 2
    can use an each right to speed this up but not as readable: key[d] where `jpm in/: value d – emc211 Feb 12 '18 at 14:23
1

The answers you have received so far are excellent. Here's my contribution building on Ryan's answer:

{[val;dict]raze {where y in/:x}[dict]'[val]}[`msft`jpm`gs;d]

The main difference is that you can pass a list of values to be evaluated and the result will be a list of keys.

[`msft`jpm`gs;d]

Output:

`tech`fin`fin

user91991993
  • 705
  • 5
  • 11