(solved) Algo: Finders Keepers : what I'm missing?

Hello guys :nerd_face:
So, here’s my solution :

function findElement(arr, func) {
  arr.filter(func) ? arr.filter(func)[0] : undefined
}

findElement([1, 2, 3, 4], num => num % 2 === 0);

// It passes the first one, but on second call,
// test doesn't pass, saying "Should return 8".
findElement([1, 3, 5, 8, 9, 10], num => num % 2 === 0)

What am I missing ? Because if I log, the answer is good :thinking:

your function doesn’t have a return statement

other than that I would need you to provide the challenge link to know what’s wrong

You forgot a return statement.

Also, filter always returns an array, and empty arrays [] are truthy, so the ternary operator is pointless.

Also, I suggest you check out the find Array method:

1 Like

Damned! Indeed @ILM , I totally forgot the return statement. I thought that was “? (return) X : (return) Y” hihi

Pardon my memory, thank you

And indeed, I got misdirected by the test saying it’s good.
As

arr.filter(func)[0]

return automatically undefined, ternary operator is useless indeed.

Thanks.

ps : yeah I saw the find in the solution, great :wink: But I wanted to succed with my filter solution :smiley:

Here is the new solution then :+1:t2:

function findElement(arr, func) {
  return arr.filter(func).length > 0 ? arr.filter(func)[0] : undefined
}

Thank you to both of you

what value has this if the length is 0?

do you really need to iterate twice over the array?

1 Like

It’s undefined indeed :slight_smile:
Okay, let me make a better one :

const findElement = (arr, func) => arr.filter(func)[0]

:smiling_face_with_three_hearts:

@GregFR You solved the problem and that’s great! I’m not trying to get you down, but there’s always room for improvement so I want to point some things out.

Filter creates a new array in memory with all the values that return a truthy value when passed into func. In a worst-case scenario, let’s say you have an array made up of a million elements, and every element is the string “foo”. Let’s say that the func callback is x => x === 'foo'. When you pass those to filter, it’s going to make a new million-item-long array of “foo” in memory. This creates a lot of waste, especially when the element has already been found at index 0, there was no need to check the rest of the 999,999 elements.

Secondly, semantically when I see filter in a piece of code, I expect that the filtered array has a purpose as to be an array. In this case it does not, all we care about is a single element.

So the reason I suggested the find method above was not only because it’s simpler to read and understand, it’s also more efficient (it short-circuits once it has found an element). If not the find method, then a for loop could also be written to short-circuit.

I understand if you’ve just learned about the filter method and want to get used to using it, but I just don’t think it’s the right tool for the job in this situation.

1 Like

Thank you for your explanation Colinthornton !!

I totally agree with you. I was aware already that filter goes through the entire array, thanks for a project I made (I was checking if filter.length was true, but I replaced with arr.some, awesome method also), and here I got mislead indeed with the findElement having just an tiny array so I went with filter :slight_smile:

I understand that find does the job perfectly here, thank you for all your information. Very interesting to read that again (until it fixes itself in my head ^^)

No problem. And I want to reiterate, code that works, no matter how efficient or inefficient, is more valuable than code that doesn’t work.