0

As an exercise in higher order functions, I am attempting to code the entire underscore JS library from scratch. I am stuck on the following

var find = function(array, predicate) {
return reduce(array, function (previous,current) {
    if (previous !== undefined) {
        return previous;
    }
    else if (predicate(current) === true)
        {return current};

}, undefined)

}

My forEach and reduce functions:

var forEach = function(collection, callback) {
    if (Array.isArray(collection)) {
        for (var i = 0; i < collection.length; i++)
            callback(collection[i], i, collection);
    }
    else {
        for (var i in collection) {
            callback(collection[i], i, collection);
        }
    }
};

var reduce = function(collection, callback, startValue) {
    forEach(collection, function (element) {
        if (startValue !== undefined) {
            startValue = callback(startValue, element);
        }
        else {
            startValue = element;
        }
    });
    return startValue;
}

I used the following predicate function to test:

var isOdd = function(x) { 
    if (x%2 === 1) {
        return true
        }
    else {
        return false;
    }
};

you'll see that the function find returns the first value in an array rather than the first odd number in the array.

what's most interesting is that when I write the function with the original arr.reduce function like so:

var finder = function(arr, test){
  return arr.reduce(function(memo, curr){
    if (memo === undefined){
      if (test(curr)){return curr;}
    }
    return memo;
  },undefined);
};

any ideas?

6
  • what's the question? Commented Sep 16, 2015 at 1:46
  • find in its current iteration is not working. why? The Find function currently outputs the first value in the array rather than the first value that passes the predicate function with value true Commented Sep 16, 2015 at 1:47
  • Underscore, uh, has annotated source available. Commented Sep 16, 2015 at 1:51
  • true, but the annotated source does not code it with reduce. additionally, it's written for both objects and arrays Commented Sep 16, 2015 at 1:55
  • There is a reason it is not coded with reduce - it is inefficient. Commented Sep 16, 2015 at 1:57

1 Answer 1

1

EDIT after a bit of thought: At start, because startValue is undefined, startValue = element (i.e. the first element of the array). After that, your callback gets called, but since previous is not undefined (and is, in fact, the first element in the array), it returns previous (the first element in the array).

Also, note that if your callback ever returns undefined, your reduce will do the wrong thing. If a starting value is not provided, you should call callback and start from the second element, outside the loop, or trigger this behaviour in the loop on index being 0.

Sign up to request clarification or add additional context in comments.

1 Comment

I believe reduce is being called on each element for as long as startValue is undefined. efficiency issues aside, is there a reason why find traverses the entirety of the array, but still only returns the first value?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.