0

G'day

While in strict mode, is there a way to search a Map via value rather than key?

Say I have a Map:

$temp = Map{'melon', 'apple'};

How could I search via value?

Tim
  • 176
  • 1
  • 15

1 Answers1

1

First, the Map in your example isn't a valid Map. Maps in Hack are key-value pairs, and you only provided keys. I assume this is a typo, and the example you meant to give was something like

$temp = Map {'fruit' => 'apple', 'veg' => 'carrot'};

To search a map in Hack, you can do the same thing you would in PHP: iterate over it in an O(n) scan. Here's an example function that does so, written with Hack generics so it will have the right type no matter the input Map.

function find_key<Tk, Tv>(Map<Tk, Tv> $haystack, Tv $needle): ?Tk {
  foreach ($haystack as $k => $v) {
    if ($v === $needle) {
      return $k;
    }
  }
  return null;
}

However, a final question back to you: why are you searching a Map like this? Maps were meant to have fast value lookup for a given key, as well as fast iteration over all key/value pairs. They are not designed for value lookup like this -- that's why it takes an O(n) loop, which should set off warning signs that what you're doing might not be the best. You may want to consider using a more appropriate data structure: maybe building an inverse map if you're doing this operation often, or using a Set or a Vector depending.

Josh Watzman
  • 7,060
  • 1
  • 18
  • 26
  • I was reading the docs and they said to use Maps as much as possible. I was not aware that Maps require a key-value pairs. I assumed they would add an element to the end of the object similar to how arrays work in php. The second question why. I have multiple arrays that are designed to be searched via value and if the value exists in one of these arrays, it is meant to return a constant. I assumed perhaps Map had a function like "contain", but searchs on value not key. – Tim Jul 12 '15 at 22:54
  • 1
    Maps very deliberately do not behave like PHP arrays, in order to avoid the confusion of what exactly the semantics are supposed to mean that you see a lot in PHP arrays -- the behavior of `array_merge` exemplifies this complexity. That's why there's `Vector` and `Set`, which depending on *why* your Map is "designed to be searched by value" might be a better replacement. Searching a Map by value is almost never a good idea and indicative of bad design. Can you link me to the docs page that said to always use a Map, we should fix/clarify it. – Josh Watzman Jul 13 '15 at 04:24
  • I have misread the information, http://docs.hhvm.com/manual/en/hack.arrays.php - Says: The Hack language guidance is to use collections whenever and wherever possible. Apologies. I had taken what was said out of context. I'll use "Sets" as they appear to be what I would like to use. – Tim Jul 14 '15 at 07:35