lodash:从对象数组中计算值

时间:2016-05-16 10:30:17

标签: javascript lodash

我有一个像这样的对象数组:

[
{"question":"Q1","answer":"my answer 2"},
{"question":"Q1","answer":"my answer"}
{"question":"Q1","answer":"my answer"}
{"question":"Q2","answer":"answer 2"}
]

我想按问题键分组并返回每个答案的计数。

e.g。

{
    "Q1": [{
        "answer": "my answer",
        "count": 2
    }, {
        "answer": "my answer 2",
        "count": 1
    }],
    "Q2": [{
        "answer": "answer 2",
        "count": 1
    }]
}

我可以使用以下groupBy个问题: .groupBy("question")并使用.countBy()计算值的出现但我不确定如何组合分组和计数功能以实现所需的输出?

3 个答案:

答案 0 :(得分:2)

您可以从_.groupBy(array, 'question')开始 - 然后使用.map

例如:

var arr = [
{"question":"Q1","answer":"my answer 2"},
{"question":"Q1","answer":"my answer"},
{"question":"Q1","answer":"my answer"},
{"question":"Q2","answer":"answer 2"}
];

var result = _(arr)
  .groupBy('question')
  .map(function(item, itemId) {
    var obj = {};
    obj[itemId] = _.countBy(item, 'answer')
    return obj
  }).value();

console.log(JSON.stringify(result, null, 2));

请参阅:http://jsbin.com/wixoronoqi/edit?js,console

上的工作版本

答案 1 :(得分:0)

A"原生javascript"使用Array.forEachArray.push函数的解决方案:

var arr = [{"question":"Q1","answer":"my answer 2"},{"question":"Q1","answer":"my answer"}, {"question":"Q1","answer":"my answer"}, {"question":"Q2","answer":"answer 2"}];

var result = {};
arr.forEach(function(v){
    var key = v['question'], Q = this[key], found = false;
    if (Q) {
        var len = Q.length;
        while (len--) {
            if (Q[len]['answer'] === v['answer']) {
                Q[len]['count']++;
                found = true;
            }
        }
        if (!found) Q.push({'answer': v['answer'], 'count' : 1});
    } else {
        this[key] = [];
        this[key].push({'answer': v['answer'], 'count' : 1});
    }
}, result);

console.log(JSON.stringify(result, 0, 4));

输出:

{
    "Q1": [
        {
            "answer": "my answer 2",
            "count": 1
        },
        {
            "answer": "my answer",
            "count": 2
        }
    ],
    "Q2": [
        {
            "answer": "answer 2",
            "count": 1
        }
    ]
}

答案 2 :(得分:0)

这里是使用Array.reduce()(有无spread operator时)的本机/原始js解决方案。

具有传播运算符,样式不变:

const questions = [
  {"question":"Q1","answer":"my answer 2"},
  {"question":"Q1","answer":"my answer"},
  {"question":"Q1","answer":"my answer"},
  {"question":"Q2","answer":"answer 2"}
];

const groupedQuestions = questions.reduce( (g, q) => {
  return {
    ...g,
    [q.question]: {
      ...g[q.question],
      [q.answer] : (g[q.question] && g[q.question][q.answer] || 0) + 1
    }
  }
}, {})

document.write(JSON.stringify(groupedQuestions))

没有传播算子:

const questions = [
  {"question":"Q1","answer":"my answer 2"},
  {"question":"Q1","answer":"my answer"},
  {"question":"Q1","answer":"my answer"},
  {"question":"Q2","answer":"answer 2"}
];

const groupedQuestions = questions.reduce( (g, q) => {
  typeof g[q.question] !== "undefined" || (g[q.question] = {});
  typeof g[q.question][q.answer] !== "undefined" || (g[q.question][q.answer] = 0);
  g[q.question][q.answer] += 1;
  return g;
}, {})

document.write(JSON.stringify(groupedQuestions))