下划线:通过对象映射(即使未定义)

时间:2014-07-21 14:17:58

标签: javascript map underscore.js

我是功能性javascript的新手,我想创建一个循环遍历对象属性的地图,并告诉我该属性是否未定义

我在寻找其他答案之后尝试过:

var _ = require('underscore');
var elements = {
    user_id: 1,
    role: 'admin',
    username: undefined,
    status: 1,
    credits: undefined,
    timestamp: 12345
};
console.log(elements);
_.object(_.map( elements, function(v,k) {
    console.log(k, v);
}));

但是我坚持这个错误:

result[list[i][0]] = list[i][1];
                      ^
TypeError: Cannot read property '0' of undefined
    at Function._.object (/private/tmp/node_tmp/node_modules/underscore/underscore.js:539:23)
    at Object.<anonymous> (/private/tmp/node_tmp/test.js:11:3)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

编辑:

我想要实现的是一个函数,给定某个对象,检查属性是否已定义且类型是否正确。我现在拥有的是:

function isNumeric(value) {
    return /^\d+$/.test(value);
}

function parseElement(elements, QuerySchema) {
    errors = [];
    // TODO: more functional with underscore
    for(var key in elements) {
        if(!elements.hasOwnProperty(key) || !(elements[key])) {
            errors.push({code:'1', description:'Missing parameter', params:[key]});
        } else {
            var val = elements[key];

            if( QuerySchema[key]==Number && !isNumeric(elements[key])) {
                errors.push({code:'2', description:'cast error', params:[key, elements[key]]});
            } else {
            }
        }
    }
    return errors;
}

并像这样使用它:

    var elements = {
        user_id: req.query.user_id,
        asset_id: req.query.asset_id,
        time_start: req.query.time_start,
        duration: req.query.duration,
        status: req.query.status,
        timestamp: req.query.timestamp
    }

    var Schema = {
        user_id: Number,
        asset_id: Number,
        time_start: Number,
        duration: Number,
        status: Number,
        timestamp: Number
    };

    var errors = parseElement(elements, Schema);
    ...

2 个答案:

答案 0 :(得分:1)

_Objects将数组转换为对象。传递单个[键,值]对列表或键列表以及值列表。如果存在重复键,则最后一个值获胜。

_.object(['moe', 'larry', 'curly'], [30, 40, 50]);

=&GT; {萌:30,拉里:40,卷曲:50}

_.object([['moe', 30], ['larry', 40], ['curly', 50]]);

=&GT; {萌:30,拉里:40,卷曲:50}

因为在你的_map函数中你没有构建正确的数组,所以它给了你那个错误。 试试:

_.object(_.map( elements, function(v,k) {
  return [k,v];
})); 

你的解析元素功能并不是那么花哨。

function parseElement(elements, Schema) {
 return _.map(elements, function(obj, key) {
 return (obj != null && Schema[key] === obj.constructor) ? true : false;
})};

此函数为您提供了一个true和false数组。您可以通过数组索引查看哪个值适合您,哪个值不适合

答案 1 :(得分:1)

不要害怕阅读underscore.js源代码。

如果你只是检查一个对象,那么你应该使用_.each() http://underscorejs.org/docs/underscore.html#section-13

如果您尝试过滤掉未定义的元素,那么您应该使用像_.reject()这样的内容(我只是查看了文档:http://underscorejs.org/#reject


在仔细研究了您正在做的事情后,您应该遍历Schema对象的,并针对elements对象进行检查。

如果没有为您完成工作,我建议您查看_.keys() - http://underscorejs.org/#keys


如果您对闭包不够熟悉,可以使用以下方法编写支票:

var pass_check = true,
    last_error = '';

_.each( obj, function( value, key ){
    if ( /* key check */ ) {
        pass_check = false;
        last_error = "Failed check: " + key;
    }
    if ( /* value check */ ) {
        pass_check = false;
        last_error = "Failed check: " + value;
    }
});