Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning value in underscore each loop does not stop the function

I noticed a strange behaviour, at least one I don't understand, while returning value inside an underscore each loop. My code is the following, it basically test wether or not an element is already present in an array based on its id, like this :

var elements = [{id: "1", name : "foo"},{id : "3", name: "bar"}];

element_exists = function(key, val){
    _.each(elements,function(element){
        console.log(element[key], val);
        if(element[key] == val){
            console.log("element exists");
                return true;
        }
   });
   return false;
};

console.log("true : ", element_exists("id", "1"));
console.log("false : ", element_exists("id", "2"));

I get the following log in the console :

1 1
element exists
3 1
true : false
1 2
3 2
false : false

My question is why does the function does not return true for the first element ?

like image 382
ltbesh Avatar asked Jun 29 '26 16:06

ltbesh


2 Answers

@ltbesh You are getting it wrong! The function does return the value & stop. It only continues executing the iterator function for the remaining elements in the input.

You are confusing loop statements with _.each method.

The second parameter to the _.each method is an iterator function. It is basically a function that is executed for every element of the array. So, if you write a return statement in your iterator function, it only terminates that particular function call. The function continues to be called for the remaining elements in the array.

Update


UnderscoreJS solution

What you need to use instead is _.find or _.some underscore methods. (Well, now that its 2020 it is high time we abandon using underscore and lodash to get functionality that ES6 provides out-of-the-box). But, since the question is about underscoreJS, I'll first provide a solution using underscore.

var elements = [{id: "1", name : "foo"},{id : "3", name: "bar"}];

element_exists = function(key, val){
    return _.find(elements,function(element){
        return element[key] === val;
   });
};

console.log("true : ", element_exists("id", "1"));
console.log("false : ", element_exists("id", "2"));
<script src="https://underscorejs.org/underscore-min.js"></script>

ES6 based solution

Now, just to show how succinct it is to accomplish the same functionality in ES6 without any external library, here's the ES6 version:

var elements = [{id: "1", name : "foo"},{id : "3", name: "bar"}];

element_exists = (key, val) => (
    elements.find(element => element[key] === val)
)

console.log("true : ", element_exists("id", "1"));
console.log("false : ", element_exists("id", "2"));

PS: If you only want to check if the element exists and don't want it to be returned by your element_exists method, switch from using find to some.

like image 105
Vikram Deshmukh Avatar answered Jul 02 '26 21:07

Vikram Deshmukh


This is happening because you're always returning false from the function.

Rewrite to this if you want to keep on using the each() function.

var elements = [{id: "1", name : "foo"},{id : "3", name: "bar"}];

element_exists = function(key, val){
  var someFlag = false;  
  _.each(elements, function(element){
        console.log(element[key] +" - "+ val);
        if(element[key] == val){
            console.log("element exists");
            someFlag = true;
        }
   });
   return someFlag;
};

console.log("should be true : " + element_exists("id", "1"));
console.log("should be false : " +element_exists("id", "2"));
like image 28
Henrik Andersson Avatar answered Jul 02 '26 21:07

Henrik Andersson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!