将SQL行转换为嵌套对象数组

时间:2020-06-24 07:46:22

标签: javascript node.js json sqlite express

在Node.js和Express中,我正在创建一个带有问题和响应的民意调查应用程序。我正在写一条从一系列sqlite表获取数据的路线。我想将此平面数据表转换为嵌套对象数组。

我使用db.all获取一个看起来像这样的数据表:

pollId | question        | optionId | option   | responseId | responseName
---------------------------------------------------------------------------
1      | Question text   | 1        | Answer 1 | 18         | Joe Bloggs
1      | Question text   | 1        | Answer 1 | 19         | Jane Doe
1      | Question text   | 2        | Answer 2 | 15         | Dave Black
2      | Second question | 1        | Yes      | 20         | Susan Green

我想将此数据转换为如下所示的对象数组:

[{
  pollId: 1,
  question: "Question text",
  options: [
    {optionId: 1, option: "Answer 1", responses:[
      {responseId: 18, responseName: Joe Bloggs},
      {responseId: 19, responseName: Jane Doe}
    ]},
    {optionId: 2, option: "Answer 2", responses:[
      {responseId: 15, responseName: Dave Black},
    ]}
    ]
},
{
  pollId: 2,
  question: "Second question",
  options: [
    {optionId: 1, option: "Yes", responses:[
      {responseId: 18, responseName: Susan Green}
    ]}
    ]
}]

做到这一点的最佳方法是什么?我应该只是遍历行吗?还是更复杂的东西?

1 个答案:

答案 0 :(得分:2)

我喜欢使用Array.reduce来对行进行分组。

const rawData = [
  {
    pollId: '1',
    question: 'Question text',
    optionId: '1',
    option: 'Answer 1',
    responseId: '18',
    responseName: 'Joe Bloggs',
  },
  {
    pollId: '1',
    question: 'Question text',
    optionId: '1',
    option: 'Answer 1',
    responseId: '19',
    responseName: 'Jane Doe',
  },
  {
    pollId: '1',
    question: 'Question text',
    optionId: '2',
    option: 'Answer 2',
    responseId: '15',
    responseName: 'Dave Black',
  },
  {
    pollId: '2',
    question: 'Second question',
    optionId: '1',
    option: 'Yes',
    responseId: '20',
    responseName: 'Susan Green',
  },
];

const groupped = rawData.reduce((result, row) => {
  result[row.pollId] = result[row.pollId] || {
    pollId: row.pollId,
    question: row.question,
    options: {},
  };

  result[row.pollId].options[row.optionId] = {
    optionId: row.optionId,
    option: row.option,
    responses: [],
  };

  result[row.pollId].options[row.optionId].responses.push({
    responseId: row.responseId,
    responseName: row.responseName,
  });

  return result;
}, {});

const final = Object.values(groupped).map((poll) => {
  poll.options = Object.values(poll.options);
  return poll;
});

console.log(final);