3

Let's say, I have a vec<int> containing a list of integers that may be non-continuous (due to element being removed from database).

Example:

$occupiedNumbers = vec[1, 2, 3, 5, 6, 8, 10, 11, 12, 13, 15, 16];

Now what I need is to check if this vec contains a given number, and if yes, increase it by 1 and repeat checking.

$newItemNumber = count($occupiedNumbers);
while (/* check if $occupiedNumbers contains $newItemNumber */) {
    $a++;
}

In vanilla PHP there is in_array() for this, but would that work for a vec? Also, there is a builtin HH\Vector::linearSearch() but it's meant to be used with vec's predecessor, HH\Vector.

What is the right solution to check if a vec contains a given value?

Neither HHVM nor Hack docs say about that use case for a vec. Also, I'm missing some sort of REPL tool to check it manually off-project without building a whole (possibly faulty) project.

Lukasz032
  • 354
  • 4
  • 14
  • 1
    The HHVM repl is invoked by `hhvm -m debug`. It's a very comprehensive REPL: type "?" at the prompt for commands. – concat Dec 06 '20 at 04:19

2 Answers2

4

The recommendation from the HHVM/HackLang guys is to use C\contains() as you can read here but you need to install the HSL package (hhvm/hsl) using composer. This library contains loads of functions to deal with the new array-type structures: vec, dict, keyset. Those functions in the HSL Library are prefixed with C, Vec, Dict, Keyset and you'll find also Math, Str, etc., very useful for other needs.

After installing that package it becomes available but typically it is more handy to add use namespace to avoid the long prefix:

use namespace HH\Lib\C;

This is how you can do it:

$exists = C\contains($occupiedNumbers, $newItemNumber);
Lucky Brain
  • 1,551
  • 12
  • 14
  • 2
    Kinda disappointed to see that **key** functions of type manipulation not being builtins and instead pushed to an external library, while legacy functions left as builtins - it's sort of inconsistent :) – Lukasz032 Dec 06 '20 at 12:58
  • I absolutely agree with @Lukasz032 , I would have expected to be able to use it like `$occupiedNumbers->contains($newItemNumber)` but the **HackLang** guys decided to go the other way. You had the `Map`, `Set` and `Vector` classes with all those methods built in but they are considering them as "legacy" and discouraging them for some reason. – Lucky Brain Dec 06 '20 at 16:53
  • 1
    @LuckyBrain I agree that HSL should want to be built in, but there's good reason why the collection types are no longer objects (re: the `->`syntax). See [this answer](https://stackoverflow.com/a/59806357/3925507) for details. – concat Dec 06 '20 at 21:01
  • @Lukasz032 as of earlier this week [HSL is now built-in to Hack!](https://hhvm.com/blog/2021/05/04/hhvm-4.108.html) – concat May 07 '21 at 16:39
1

If you are really looking for the longest continuous interval starting from count($occupiedNumbers) then it may be much faster to find its initial index in the sorted list (if it exists), then use direct indexing from there:

// `use namespace HH\Lib\{C, Vec};` at top level
$occupiedNumbers = vec[1, 2, 3, 5, 6, 8, 10, 11, 12, 13, 15, 16];

$sorted = Vec\sort($occupiedNumbers); // if not sorted in general
$size = count($sorted);
$v = $size;
$i = C\find_key($sorted, $w ==> $w === $v);
if($i !== null) {
  for(; $i < $size - 1 && $sorted[$i + 1] === $v + 1; $i++, $v++) {
  }
}
// $i is null | <index of largest number in continuous interval>
concat
  • 3,107
  • 16
  • 30