Where do I Belong -- tests failed, not sure why

Tell us what’s happening:

I have no idea why my code is failing the tests.
As you can see from the code, logging the results of the first three arrays in the test set does seem to return the correct values, and yet they all fail.

Your code so far


function getIndexToIns(arr, num) {

const sorted = arr.sort((a , b) => a - b );
console.log(sorted);

let targetIndex = 0;  // NOT USED, was part of another attempt

for (let i in sorted) {
  if (sorted[i] == num){
    return i;
  } else if (sorted[i] > num){
    return i;
  } 
}
}

console.log(getIndexToIns([10, 20, 30, 40, 50], 35))

console.log(getIndexToIns([10, 20, 30, 40, 50], 30))

console.log(getIndexToIns([40, 60], 50))

Your browser information:

User Agent is: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/83.0.4103.61 Chrome/83.0.4103.61 Safari/537.36.

Challenge: Where do I Belong

Link to the challenge:

Aha! I just checked and the returned values are strings not numbers, but I am not sure why…

I figured it out – part of the solution hinges on NOT using the syntax:

for (let i in sorted)

but instead the usual:

for (let i = 0; i < sorted; i++)

But I thought they were supposed to be equivalent ways of writing for loops. Is there a javascript master out there who can explain the difference between these?

And sorry if I am talking to myself here!

This is because arrays in JavaScript are not like arrays in other programming languages. They are technically a normal JS objects. Object keys are always strings (JS converts the numbers for you). In fact, you can do something like this:

const x = [2,4,6];
x[1.25] = true;
x[-1] = true;
console.log(x);
// expected output: [ 2, 4, 6, '1.25': true, '-1': true ]

So basically, because Arrays are really just objects, these are almost equivalent:

const arr = [1,2,3];
const arr2 = {
    "0": 1,
    "1": 2,
    "2": 3
};

The only difference between arr and arr2 is the special array length property. All other functionality is the same. Don’t actually create arrays the second way, because it’s harder to read and browsers usually can’t make as many array-specific optimizations.

When you use for (let i in arr), you iterate over the literal string keys of an object (or array). When you use the normal for loop, you’re creating an actual integer.

1 Like

The for...in operator loops through the string keys of an object. Maybe you’re confusing it with for...of?

This works, but notice that both statements are doing the same thing (return i). You could condense this down to one if statement.

if (sorted[i] >= num) {
  return i;
}
1 Like

I thought that might be the case, but then I couldn’t get things to work with for ... of. I had recently come across a blog post somewhere that I took to mean that we could always eliminate the clunky syntax of the typical for loop, but I may have misunderstood.

I’ll try condensing the two statements into one. I also needed to add a final else clause to catch cases where the num parameter was greater than all of items in the array.

Thanks for your help!

Here is the working code:

function getIndexToIns(arr, num) {
  
  const sorted = arr.sort((a,b) => (a - b));
  const len = sorted.length;
  
  for (let i = 0; i < len; i++){
    if (sorted[i] >= num) {
      return i;
    }
  }
  return len;
}

If I substitute for (let i of sorted) for the normal for loop setup code, I get the length of the array in every case – in other words it fails to jump out of the loop when the condition evaluates true and seems to just iterate through all of the array until the end.

On the other hand if I use for (let i in sorted) the iteration stops at the right time, returning the index I am after, but as a string. :stuck_out_tongue:

There are subtle differences underneath these three different approaches I guess!