Lodash project on step 35 _.dropWhile()

Hi Guys,

This lesson introduced predicates to me. My experience is limited to the javascript class which I took on codecademy. I found a few articles online about predicates, read them and reread them and am starting to understand how they are used to determine truthy. I also reviewed all of the drop while posts on this forum. I’m trying to say that I’ve tried to do extra homework on this one. With that, here is my code that is inside the ‘_’ object:

  	drop(array, num){
      if(num===undefined){
        num = 1
      }
      let newArray = array.slice(num)
      return newArray
    }, // closes the drop method
  
  	dropWhile(array, predicate){
     	let dropNumber = array.findIndex(function(element, index){
  			!(predicate(element, index, array))
        return index
    	})
      let droppedArray = this.drop(array, dropNumber)
      return droppedArray
    } // closes the dropWhile method

Here’s the results when I run the test:

$ node test/drop-while.js
_.dropWhile() Tests:
1 - _.dropWhile() is defined - Passed!
2 - Returns an array - Passed!
3 - Drops elements until predicate function return
s falsy - Failed: _.dropWhile([1, 2, 0, 4], indexI
sSmallerThanElement returned [ 2, 0, 4 ] instead o
f [ 0, 4 ].
$

I’m treading water because I can’t make this code work in jsfiddle.net to debug it. So here I am, trying to persevere.

In looking at 3- from the test results above, can you point me in the right direction?

thank you

3 Likes

Isn’t that just a matter of inserting prints to find out where it goes wrong?

Why wouldn’t you be able to run it?

What is jsfiddle doing for you that’s so special? Why not run it in nodejs or even your browser?

Also, do you really feel that you need to comment where things end? If your indentation matched your braces there’d be no problem seeing that anyway, would there?

1 Like

I tried putting it in jsfiddle.net and it gives me errors. I’m probably doing something stupidly wrong.

let array = [1, 2, 0, 4]   // test array

const _ = {	 // begin object
  drop(array, num){
      if(num===undefined){
        num = 1
      }
      let newArray = array.slice(num)
      return newArray
  }, // closes the drop method
  
 	dropWhile(array, predicate){
    let dropNumber = array.findIndex(function(element, index){
      !(predicate(element, index, array))
      return index
    })
    let droppedArray = this.drop(array, dropNumber)
    return droppedArray
  } // closes the dropWhile method
} // end object
console.log(_.dropWhile(array, 2))

Yes, I tried using node which is what the codecademy interface uses and I get the same errors. I agree that I excessively comment. As a beginner, it seems to help me. I’m sure I’ll get tired of it and drop the practice.

1 Like

What I mean is that I think it’s the wrong thing to comment. The code already says that.
Aside from how something is used, what I mainly tend to write as comments is the idea behind some code, the general concept.
Sometimes I’ll write some comments on the steps to implement to get them out of my head and then work on one such step at a time.


jmw.js:14
      !(predicate(element, index, array))
        ^

TypeError: predicate is not a function

If it’s not a function then you can start asking yourself things like whether you meant for it to be, and if not, stop calling it, or if yes, then clearly you mixed things up, where did it come from?

That’s not any different from how you’d debug the wrong result you’re getting. Assess the situation, decide what’s wrong about it and find out how that came to be. Repeat until fixed.

2 Likes

That line !(predicate(element, index, array)) is something I adopted after seeing it in this post and this post. Sometimes I search the forum when I’m stuck to try and reverse figure out how it works. This lesson has no walk through video so, when you are stuck, your options for figuring it out are limited to an internet search and this forum.

In short, I have no idea how that line works (doesn’t work). I’ve read up on predicates and the line looks to me like it lacks conditional logic. I’m guessing that it checks for a valid value and if truthy, that probably means something.

I thought it would work because the use of predicate looked similar to prior steps:

 // step 27 - 30 findKey method
 findKey (object, predicate){ 
    for (let key in object){
        if(predicate(object[key])){
            return key
        }
    }
 },
1 Like

You can’t write something you don’t know what it’s supposed to do. Refer to what should happen instead, which is something you have to decide before you write anything at all.

Yup, I’ll go back and take another look at this. I just finished // chunk steps 39 - 42 which for me was much easier. Thank you for continuing to help me.

You’ve talked a lot about predicates, they’re not special… There’s really no research to be done. They look at something and say yes or no. You’ve probably already used them yourself with filter.

But you don’t seem to have thought through what the function at all does, because the way you try to call your function doesn’t at all match what it’s supposed to do. Does that mean you think that you know what it does and that’s how you called it, or does it mean you know you don’t know and decided to call it in some way regardless?

Have you read any kind of description of what the function’s behaviour is? Have you read lodash’s documentation for it? They probably have an example of how it is used too.


And that’s also the general theme of javascript. It’s a very small language. There’s uhm… numbers, strings… objects, arrays, functions. And that’s pretty much all it deals with.

Hey Jake, I also got stuck on this step, but it seems I figured it out by reverse engineering and also by following step 5 of task 37:

  1. Within the callback function, return the negated return value of predicate called with element , index , and array . We negate the value (use ! ) since we are looking to drop elements until the predicate returns a falsy value. However, .findIndex() is looking for the first truthy value. So, we make every truthy value falsy and vice versa to get the value we are looking for.

So, what I ended up doing was change your function:

let dropNumber = array.findIndex(function(element, index){
  !(predicate(element, index, array))
  return index
})

Into this:

let dropNumber = array.findIndex(function(element, index) {
      return !(predicate(element, index, array));
    });

Hope that this helps, as the instructions are sometimes vague and confusing.

4 Likes

Hi Everyone and thanks for sharing and posting. I also got stuck and here’s my solution after seeing your code of course.

  dropWhile(arr, predicate){
      let dropNumber = arr.findIndex(function(el, index, arr) {
        return !(predicate(el, index, arr));
      })
      let droppedArray = this.drop(arr, dropNumber);
      return droppedArray;
    }

Hopefully you will find it useful. Its not worth being stuck for hours!

3 Likes

Thanks deeqoo. I appreciate the answer as I ended up giving up on this for the first time at Codecadamy. Sort of sad but, I was totally stumped. I pasted in your code and it past the test. I studied the code as well but, I just don’t get it and I’m not concerned at this point. Predicates despite reading about them is still sort of a mystery to me. Oh well, I’ll loop back to it eventually.

I’ve since moved onto the web development lessons. Some of it is review which is great. I continue to learn a lot from these online classes.

1 Like

Yep, I did the same. I’ve followed everything up until now, but sometimes Codecademy doesn’t explain at all how the concept works and expects you to just type it in and move forward. The “Solve through” video they provide has the developer just simply typing the instructions, but giving very limited explanations of the underlying concepts and mechanics.

Not worth losing myself for hours over this. When and if I actually need to understand it better I’m sure I’ll go back to it eventually. I’ll move on for now.

N.

3 Likes

Hi all,

Really stuck on this one. I have read the Lodash doc and implement steps but I can’t make sense of them. I also looked at the solution provided above and can’t rationalise how one would arrive at that from the implement steps.

I did eventually pass with this:

dropWhile (arr, fn) {
  newArr = arr
  for (e in arr) {
    if (fn(e, arr.indexOf(e), arr)) {
      newArr.shift()
    }
    newArr.shift();
    return newArr
  }
},

While it works, I don’t even understand why the last newArr.shift(); line item is required. This project has been difficult and IMO feels out of place where it shows up in the Web Dev path. It’s a huge step up in complexity over the last few challenges.

Can anybody help me to better understand what’s happening in the official answer below? When I used a similar approach I kept getting ‘e is undefined’ errors.

dropWhile(arr, predicate){
  let dropNumber = arr.findIndex(function(el, index, arr) {
    return !(predicate(el, index, arr));
  })
  let droppedArray = this.drop(arr, dropNumber);
  return droppedArray;
}
dropWhile (arr, fn) {
  const falsy = (e, i) => { return !fn(e, i, arr) };
  n = arr.findIndex(falsy);
  return this.drop(arr, n)
},

Trying to make more sense of it, it looks like ‘e’ and ‘i’ (representing element and index, respectively) are assigned in the anonymous function call, and assigned a value from their respective parameters in the callback function ‘fn’ (the predicate).

Please confirm/deny? :woozy_face:

This one had me stumped and while I figured it out(which I could only do by looking at the test being ran against it), it was still very confusing.

dropWhile (array, predicateFunc) {
let dropParamNum= array.findIndex(function (element, index) {
return !predicateFunc(element, index, array);
});
let dropIfFalse= this.drop(array, dropParamNum);
return dropIfFalse;
},

The part that really held me up and still does is why the test is doing the following:

const indexIsSmallerThanElement = (element, index) => index < element;
console.log(workingTitle.dropIfFalse([1, 2, 3, 0, 5, 9, 7, 8], indexIsSmallerThanElement));

I should say, I understand what it is doing. I do not understand why it is doing the ‘index < element’ part.

@cbmidkiff9355229650 “index < element” should evaluate to true or false.
i.e. console.log(workingTitle.dropIfFalse([1, 2, 3, 0, 5, 9, 7, 8], true/false));

This worked great for me, thank you very much! Why is it not working with a lambda expression? Is this a limitation of codecademy or should I avoid lambda functions in array.findIndex calls?

thanks @bozko for this solution. solved!