Function subLength()

I’m having trouble understanding the logic for the subLength() function in the practice section for arrays, loops, objects and iterators for the full-stack engineer path. Can someone explain it to me step by step?

// Write function below
const subLength = (str, char) => {
  let charCount = 0;
  let len = -1;
  
  for (let i=0; i<str.length; i++) {
    if (str[i] == char) {
      charCount++;
      if (charCount > 2) {
        return 0;
      }
      if (len == -1) {
        len = i;
      } else {
        len = i - len + 1
      }
    }
  }
  if (charCount < 2) {
    return 0;
  }

  return len;
};
8 Likes

I approached this problem from the false case perspective and deal with that issue, first.

const subLength = function (str, chr) {
  let y = str.split('').filter(x => x === chr)
  if (y.length !== 2) return 0
  // ...
}

It’s a bit convoluted, perhaps, but it weeds out all the cases for this type of return.

Now we can get into the logic knowing that we have exactly two instances of chr in str.

  const m = str.indexOf(chr)
  const n = str.lastIndexOf(chr)
  y = str.substr(m, n)

That gives us our return value…

  return y.length
}

Now I may have cheated and not did the character count as you did, my bad, but that is the right idea. Only thing to change there is > 2. We also want to catch less than 2, as well; ergo, !== 2. That is where your logic should escape the loop and begin anew.

Use the loop you have for only determining whether to return 0, or not. Now work on the logic of the string we know to exist with a length of at least 2. Locate the index of those two characters and capture them and everything in between.

5 Likes

the thing that i don,t understand is in the example below :
subLength(‘Saturday’, ‘a’); // returns 6
subLength(‘summer’, ‘m’); // returns 2
why in the first example it return 6 and inthe second example it return 2

1 Like
'aturda'  =>  6 characters
'mm'      =>  2 characters
4 Likes

Can someone tell me why this won’t pass?

function subLength(aString, sChar) {
  let word = [];
  const array2 = [];
  var count = 0;
  for (let i = 0; i < aString.length; i++) {
    word.push(aString[i]);
    if (word[i] == sChar) {
      //console.log(i)
      num = i
      array2.push(i)
      count++
    }
  }
  //console.log(word)
  //console.log(array2)
  if (count > 2) {
    return 0
  }
  if (count < 2) {
    return 0
  }
  return (array2[1]+1) - array2[0];

}

console.log(subLength('Saturday', 'a'));
console.log(subLength('cheesecake', 'k'));
console.log(subLength('digitize', 'i'));

This is a bit more accurate…

const subLength = function (str, chr) {
    
    let y = str.split('').filter(x => x == chr)

    if (y.length !== 2 || y.length < 2) { 
      return 0
    }
    y = str.lastIndexOf(chr) - str.indexOf(chr) + 1 // finds and substracs the index/location length of the two chars

    return y // returns and thus logs the result of the substraction
    
  }

console.log(subLength('Saturday', 'a')); // should return return 6
console.log(subLength('summer', 'm')); // should return return 2
console.log(subLength('digitize', 'i')); // should return return 0
console.log(subLength('cheesecake', 'k')); // should return return 0

Because the following code…

console.log(subLength('summer', 'm')); 

…should return 2., yet, it returns 3 if you use mtf’s solution.

2 Likes

Delete the,

num = i 

…from your code.

1 Like

Finally somebody spotted the error. It was left in there to test the learners. .substr() is the wrong method for the job. The only line that needs to change is this one,

y = str.substring(m, n + 1)

and that would have been discovered earlier if a learner read the docs for substr and substring. There is a subtle difference between the two.

5 Likes

Thanks @ghost_in_the_shell I was losing my mind. This feels like some of the first code I ever wrote haha. Crazy how far I’ve come since here.

Happy to hear that you kept coding and improving! :slight_smile:

I recently started learning how to code myself and had no idea if it was worth even replying to this post since it was created some time ago.
I hope it will come in handy to someone else on the way.

1 Like

I finally had someone like an answer I gave on a post I made after I discovered the answer. It’s always nice to get feedback. The thing that was throwing me off was the code was working correctly even with that statement in it. Just codecademy didn’t like it.

Yeah, I sometimes have the same issue. It hasn’t been frustrating, yet. However, the loudly project that I recently went through was a drag. For some reason all of the node.js commands were not working for me.

Hello

Could someone help me ? Why my code output comes out '0 ’ in all ? The argument said ’ If there are less than 2 or more than 2 occurrences of the character the function should return 0." which i did but it is showing 0 , what is the reason please ?
thanks

const subLength = (str, char) => {
let x = str.split(' ').filter(y => y == char)
if (x.length < 2 ) {
  return 0;
} else if ( x.length > 2) {
 return 0;
}
else if (x.length == 2 ) {
  return str.lastIndexof(chr) - str.indexOf(char) +1 } 
  else {
    return undefied; 
  }
}

console.log (subLength('Saturday' , 'a'));
console.log (subLength('summer', 'm')); 
console.log (subLength('digitize', 'i')); 
console.log (subLength('cheesecake', 'k'));

Try printing to see what is happening. For example:

I edited your post to format the code for readability. Please review: How do I format code in my posts?

Hello
Thank you, i have read ’ How do i format code in my posts? ’ . I understood my codes should be put in ``` there right? I also tried console.log(x) under x=str.split (’ ’ ) , it is showing : , 0 , , 0 , , 0 . I cannot find the bug yet :frowning:

const subLength = (str, char) => {
let x = str.split(' ').filter(y => y == char)
console.log(x);
if (x.length < 2 ) {
  return 0;
} else if ( x.length > 2) {
 return 0;
}
else if (x.length == 2 ) {
  return str.lastIndexof(chr) - str.indexOf(char) +1 } 
  else {
    return undefied; 
  }
}

console.log (subLength('Saturday' , 'a'));
console.log (subLength('summer', 'm')); 
console.log (subLength('digitize', 'i')); 
console.log (subLength('cheesecake', 'k'));

The first problem you’re having is this portion:

let x = str.split(' ')

Since you’re splitting with a space, which none of the words have, it’s returning an array of just one element with the whole word. Example: 'Saturday' becomes [ 'Saturday' ]. Then you’re trying to use filter() on it and comparing it to only one character, so it will never have any matches.

If you used split('') without a space, then you’d have something to work with and can continue debugging and exploring your idea for the solution.

1 Like

Thank you @selectall , so now i changed .split without space and another error came out . It said as below :
return str.lastIndexof(char) - str.indexOf(char) +1 ;
^TypeError: str.lastIndexof is not a function

Why this is showing please?

``const subLength = (str, char) => {
let x = str.split(’’).filter(y => y == char)
if (x.length > 2 ) {
return 0;
}
else if ( x.length < 2) {
return 0;
} else if (x.length === 2 ) {
return str.lastIndexof(char) - str.indexOf(char) +1 ;
}
}

console.log (subLength(‘Saturday’ , ‘a’));
console.log (subLength(‘summer’, ‘m’));
console.log (subLength(‘digitize’, ‘i’));
console.log (subLength(‘cheesecake’, ‘k’));

`

@arc2779423039 The error message is giving you an important clue. If it’s saying that it isn’t a function and you know it should be, then double check the spelling. Also, keep in mind that JavaScript is case-sensitive so lastIndexof is not the same as lastIndexOf

1 Like

@selectall
Thank you, i have no more error but the problem is all outputs are coming out 0,0,0,0 instead of 6,2,0,0.
Could you see where i am wrong ?

``
const subLength = (str, char) => {
let x = str.split(’ ').filter(y => y == char)
if (x.length > 2 ) {
return 0;
}
if ( x.length < 2) {
return 0;
}

if (x.length === 2 ) {
return str.lastIndexOf(char) - str.indexOf(char) +1 }
}

console.log (subLength(‘Saturday’ , ‘a’));
console.log (subLength(‘summer’, ‘m’));
console.log (subLength(‘digitize’, ‘i’));
console.log (subLength(‘cheesecake’, ‘k’));

Yes, you’re back to the original issue you posted about because you’re splitting by space. You corrected it in a post after that, but you may have gone back to an earlier version of the code by mistake.

1 Like