简体   繁体   中英

Why is `_.map` returning undefined when I return `false`?

I have a function, which maps an array with underscore . Here is the function:

var services = _.map(userCopy.get('services'), function (service) {
    if (service.service_selected === true) {
        return service;
    }
});

My problem is that when the conditional === false , then I get undefined put into services . Of course I can remove the undefined , but that is ugly and I just want to use map correctly. How do I fix this?

_.map uses whatever the function returns, to build the result. If a function doesn't return anything explicitly, JavaScript returns undefined . That's why the result of _.map has undefined whenever the condition fails.

What you actually need, is a _.filter

var services = _.filter(userCopy.get('services'), function(service) {
    return service.service_selected === true;
});

_.filter accepts a collection and a predicate function. It applies the predicate function to each and every value of the collection and if the function returns true , that element will be included in the result, if the function returns false , that element will be skipped.

Note: You can actually use _.matcher , along with _.filter , like this

var isServiceSelected = _.matcher({
    service_selected: true;
});

var services = _.filter(userCopy.get('services'), isServiceSelected);

This will be very useful if you are going to filter based on service_selected: true condition more than once. If it is just a one-time thing, then _.where shown below would be better alternative.


You can also use _.where , which can return the objects only if the current object contains all the key-value pairs listed, like this

var services = _.where(userCopy.get('services'), {
    service_selected: true;
});

Now, all the service objects will be returned which have service_selected attribute value as true .


Demo:

 function display(heading, data) { var json = JSON.stringify(data, null, 4); document.body.appendChild(document.createElement('h3')).innerHTML = heading; document.body.appendChild(document.createElement('pre')).innerHTML = json; } var data = [{ "name": "auth", "service_selected": true }, { "name": "authorization", "service_selected": false }, { "name": "faltu", "service_selected": true }]; display("_.filter", _.filter(data, function (service) { return service.service_selected === true; })); display("_.matcher", _.filter(data, _.matcher({ service_selected: true }))); display("_.where", _.where(data, { service_selected: true })); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> 

Updated my answer... This solved my problem

    var missingParamsArray = _.map(requiredParams, function (val, param) {
        if (val) {
            if (!req.user[param]) {
                return param;
            }
        }
    });

    var missingParams = _.filter(missingParamsArray, Boolean);

missingParams can also be written as

var missingParams = _.filter(missingParamsArray, function (param) {
       return param !== undefined;
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM