【问题标题】:Convert array of objects (sort of groupby)转换对象数组(groupby 排序)
【发布时间】:2017-08-05 08:04:07
【问题描述】:

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

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": [...]
}   

如果没有错误代码,我找不到正确的方法。

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

【问题讨论】:

    标签: javascript arrays sorting ecmascript-6


    【解决方案1】:

    您可以通过在最后阶段获得结果集来弥补缺失的部分。

    我将密钥从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; }

    【讨论】:

    • 哦,是的,我觉得自己很愚蠢 :) 太长时间专注于同一个问题 ^^
    【解决方案2】:

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

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

    然后我们可以使用 lodash 的 groupBy 和 map 代码会非常干净:

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

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

    【讨论】:

    • 是的,但我不想在我的应用程序中只为一个案例包含这个外部库。不过谢谢!它可能会帮助其他开发人员。
    【解决方案3】:

    当您按主题名称对问题进行分组时,您可以创建您想要的确切“主题”对象{ "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);

    【讨论】:

      猜你喜欢
      • 2017-09-13
      • 1970-01-01
      • 1970-01-01
      • 2021-10-02
      • 2019-10-01
      • 2018-03-31
      • 1970-01-01
      • 1970-01-01
      • 2018-01-29
      相关资源
      最近更新 更多