转换对象数组(groupby的排序)

时间:2017-08-05 08:04:07

标签: javascript arrays sorting ecmascript-6

我调用一个返回问题列表的服务。然后,我按主题重新组合这个问题。 我有这个转换:



var questions = [
  {
    id: 1,
    label: 'lorem ispum ?',
    theme: {
      id: 1,
      label: 'dog',
    }
  },
  {
    id: 2,
    label: 'lorem ispum2 ?',
    theme: {
      id: 2,
      label: 'horse',
    }
  },
  {
    id: 3,
    label: 'lorem ispum3 ?',
    theme: {
      id: 1,
      label: 'dog',
    }
  },
];

var groupByTheme = questions.reduce(function(obj,item){
    obj[item.theme.label] = obj[item.theme.label] || [];
    obj[item.theme.label].push(item);
    return obj;
}, {});

/*var result = Object.keys(groupsByTheme).map(function(key){
    return {theme: key, questions: groupsByTheme[key]};
});
*/

var result = Object.entries(groupByTheme).map(([theme, questions]) => ({ theme, questions }));

console.log(result);




有效。 但是现在,我想添加一个属性:主题的id。

{
    "themeId": 1,
    "theme": "dog",
    "questions": [...]
},
{
    "themeId": 2,
    "theme": "horse",
    "questions": [...]
}   

如果没有密码,我就找不到正确的方法。

有什么建议吗? 提前致谢 !

3 个答案:

答案 0 :(得分:0)

您可以通过在最后阶段获取结果集来增加缺失的部分。

我将密钥从theme更改为id,因为id看起来更独特。



var questions = [{ id: 1, label: 'lorem ispum ?', theme: { id: 1, label: 'dog' } }, { id: 2, label: 'lorem ispum2 ?', theme: { id: 2, label: 'horse' } }, { id: 3, label: 'lorem ispum3 ?', theme: { id: 1, label: 'dog' } }],
    groupByTheme = questions.reduce(function (obj, item) {
        obj[item.theme.id] = obj[item.theme.id] || [];
        obj[item.theme.id].push(item);
        return obj;
    }, {}),
    result = Object.entries(groupByTheme).map(([id, questions]) => ({
        id,
        theme: questions[0].theme.label,                              // add this
        questions
    }));

console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }




答案 1 :(得分:0)

我建议您使用lodash库。然后代码将非常干净。我将首先制作themeMap对象,该对象将从label映射到id

const themeMap = {};
_.forEach(questions, question => themeMap[question.theme.label] = question.theme.id);

然后我们可以使用lodash的groupBymap,代码将非常干净:

const result = _.map(_.groupBy(questions, question => question.theme.label), (group, key) => {
    return {questions: group, theme: key, themeId: themeMap[key]};
});

代码将不那么混乱。 如果您不想使用lodash,那么您可以通过您已经执行的javascript reduce实现groupBy。

答案 2 :(得分:0)

当您按主题名称对问题进行分组时,您可以创建所需的确切“主题”对象{ "themeId": 1, "theme": "dog", "questions": [] },并将问题推送到questions道具中。要转换为数组,请使用Object#values

var questions = [{"id":1,"label":"lorem ispum ?","theme":{"id":1,"label":"dog"}},{"id":2,"label":"lorem ispum2 ?","theme":{"id":2,"label":"horse"}},{"id":3,"label":"lorem ispum3 ?","theme":{"id":1,"label":"dog"}}];

var result = Object.values( // get an array of theme objects
  questions.reduce(function(obj,item){
      obj[item.theme.label] = obj[item.theme.label] || 
        Object.assign({ questions: [] }, item.theme); // create an object that includes theme data, and an empty array for questions

      obj[item.theme.label].questions.push(item); // push into questions

      return obj;
  }, {})
);

console.log(result);