score:2

Accepted answer

This is the expected behaviour.

If you look at the source code for d3.bisector, you'll see that it does not iterate the whole array the way you think. Have a look here:

while (lo < hi) {
    var mid = lo + hi >>> 1;
    if (compare(a[mid], x) > 0) hi = mid;
    else lo = mid + 1;
}

The interesting part lies here: var mid = lo + hi >>> 1;. What this bitwise (named zero-fill right shift) does is calculating the midpoint of the array.

In your case, the array has 78 elements. Therefore:

console.log(0 + 78 >>> 1)

And it keeps getting the midpoint of the remaining part, again and again, until finding the element. Have a look here:

let lo = 0,
  hi = 78;
while (lo < hi) {
  let mid = lo + hi >>> 1;
  console.log(mid)
	lo = mid + 1;
}

For an array of 78 elements it does that 6 times (not 5, as you mentioned), and that's why you see the console.log working only 6 times.

Have a look at this demo, an array of 78 elements, the console.log works 7 times:

const data = d3.range(78);

const bisect = d3.bisector(function(d) {
  console.log(d);
  return d;
}).left;

bisect(data, 5);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Now let's increase the array to 1000 elements. The console.log works 10 times:

const data = d3.range(1000);

const bisect = d3.bisector(function(d) {
  console.log(d);
  return d;
}).left;

bisect(data, 5);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>


Related Query