以功能方式解析结构化数据(例如,不变异)

时间:2017-02-08 08:17:14

标签: javascript algorithm parsing functional-programming immutability

想象一下,文件中包含以下数据:

Group1
  Thing1
  Thing2
Group2
  Thing1
  Thing2
  Thing3
Group3
Group4
  Thing1

编写一个“解析器”很容易,它逐行循环遍历文件,记住当前Group(在一个变量中),然后将所有Thing写入一个对象,整齐地按各自的小组分组:

// Very naive implementation for illustrative purposes only
let groups = {}
let currentGroup = null
data
  .split(/\n/)
  .forEach(entry => {
    const matches = entry.match(/^(Group\d+)$/)
    if (matches) {
      currentGroup = matches[1]
      groups[currentGroup] = []
    } else {
      groups[currentGroup].push(entry.trim())
    }
  })

给了我:

{
  Group1: [
    'Thing1', 'Thing2'
  ],
  Group2: [
    'Thing1', 'Thing2', 'Thing3'
  ],
  ...
}

以纯粹功能的方式改变groupscurrentGroup,实现这一目标的最佳方法是什么?我是否需要更加强调Array.reduce,因为我已经看到一些(恕我直言,相当令人难以置信)用例将数组转换为对象,或者这对我们没有帮助?

1 个答案:

答案 0 :(得分:2)

是的,您想在此处使用reduce

data
.split(/\n/)
.reduce(({groups, currentGroup}, entry) => {
  const matches = entry.match(/^(Group\d+)$/)
  if (matches) {
    groups[matches[1]] = []
    return {currentGroup: matches[1], groups};
  } else {
    groups[currentGroup] = groups[currentGroup].concat([entry.trim()]);
    return {currentGroup, groups};
  }
}, {groups: {}, currentGroup: null})
.groups

但是,JS没有合理的方法来创建没有变异的地图对象。只要您将财产分配保留在本地,就没有错。