Underscore.js如何计数

时间:2014-10-22 22:57:10

标签: javascript underscore.js javascript-objects

我是underscore.js库的新手,还是javascript的新手。我已成功使用countBy方法来总结我的回答。但是你如何使用countBy来计算那些不存在的东西和一些预定义的存储桶?或者我应该完全使用不同的方法吗?

考虑以下示例,这里是JSFiddle http://jsfiddle.net/itchesavvy/bfmhtp5e/2/

var data = [{
    questionData: {
        type: 'multiple choice',
        content: {
            text: 'This is the question?',
            answers: [{
                _id: 'id1',
                value: 'First answer'
            }, {
                _id: 'id2',
                value: 'Second answer'
            }, {
                _id: 'id3',
                value: 'Third answer'
            }, {
                _id: 'id4',
                value: 'Fourth answer'
            }]
        }
    },
    responses: [{
        answer: 'id1',
        timestamp: 1
    }, {
        answer: 'id2',
        timestamp: 4
    }, {
        answer: 'id1',
        timestamp: 10
    }, {
        answer: 'id3',
        timestamp: 15
    }, {
        answer: 'id3',
        timestamp: 16
    }, {
        answer: 'id1',
        timestamp: 25
    }, {
        answer: 'id2',
        timestamp: 35
    }, {
        answer: 'id3',
        timestamp: 42
    }, {
        answer: 'id1',
        timestamp: 44
    }, {
        answer: 'id1',
        timestamp: 50
    }, {
        answer: 'id2',
        timestamp: 70
    }, {
        answer: 'id3',
        timestamp: 80
    }, {
        answer: 'id2',
        timestamp: 81
    }]
}];

var b = _.countBy(data[0].responses,'answer');
console.log(b);

这会产生以下对象{id1:5, id2:4, id3:4}

我想知道如何使用来自questionData.content.answers的数据{id1:5, id2:4, id3:4, id4:0}

更重要的是,我想知道如何再次使用值字段中的questionData.content.answers中的数据来获取{'First answer':5, 'Second answer':4, 'Third answer':4, 'Fourth answer':0}

2 个答案:

答案 0 :(得分:1)

根本不确定是否需要使用下划线。

var data=[{questionData:{type:"multiple choice",content:{text:"This is the question?",answers:[{_id:"id1",value:"First answer"},{_id:"id2",value:"Second answer"},{_id:"id3",value:"Third answer"},{_id:"id4",value:"Fourth answer"}]},responses:[{answer:"id1",timestamp:1},{answer:"id2",timestamp:4},{answer:"id1",timestamp:10},{answer:"id3",timestamp:15},{answer:"id3",timestamp:16},{answer:"id1",timestamp:25},{answer:"id2",timestamp:35},{answer:"id3",timestamp:42},{answer:"id1",timestamp:44},{answer:"id1",timestamp:50},{answer:"id2",timestamp:70},{answer:"id3",timestamp:80},{answer:"id2",timestamp:81}]}}];

    //Simplify your object traversal
var questionData = data[0].questionData; 
    responses = questionData.responses,
    content = questionData.content,
    //Stage your counters
    i = 0, 
    l = content.answers.length,
    //Will hold your answers array as key value pairs for easier lookups
    answers = {},
    //Will hold the final results
    results = {}; 

//Iterate over your answers collection
for(; i < l; i++){
    //The value of each answer will be used as keys to look up counts in our results object
    var key = content.answers[i].value;
    //We will cross reference 'id#' values with the results keys
    answers[content.answers[i]._id] = key; 
    //Start each possible result with a count of zero.
    results[key] = 0; 
}

//Output our answers (cross reference object)
console.log(answers); 

//Reset our counters to the responses collection
i = 0;
l = responses.length;

//Iterate over the responses
for(; i < l; i++){
    //Use the answer within each response to look up the appropriate results key from our answers object. 
    var key = answers[responses[i].answer];
    //Increment the result value. 
    results[key]++; 
}

//Output the counts of each answer. 
console.log(results); 

答案 1 :(得分:0)

这可能不是最有效的方式,但它可以说是最具可读性的(使用下划线时)。

var questions = {};
var defaults = {};

// Build a map of 'id1' to 'First answer', etc.
// Build default value of 0 for all questions.
_.each(data[0].questionData.content.answers, function (e) {
    questions[e._id] = e.value;
    defaults[e._id] = 0;
});

// Calculate results by id: {id1: 5, ...}
var resById = _.defaults(_.countBy(data[0].responses, "answer"), defaults);
var results = {};

// Remap ids to strings: 'id1' to 'First answer', etc.
_.each(resById, function (v, k) {
    results[questions[k]] = v;
});

console.log(results);