Imagine you have the following data in a file:
想象一下,文件中包含以下数据:
Group1
Thing1
Thing2
Group2
Thing1
Thing2
Thing3
Group3
Group4
Thing1
It's easy to write a "parser" which loops through the file line-by-line, remembering the current Group
(in a variable) and then writing all the Thing
s to an object, neatly grouped by their respective group:
编写一个“解析器”很容易,它逐行循环遍历文件,记住当前组(在一个变量中),然后将所有的东西写入一个对象,整齐地按其各自的组分组:
// 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())
}
})
which gives me:
这给了我:
{
Group1: [
'Thing1', 'Thing2'
],
Group2: [
'Thing1', 'Thing2', 'Thing3'
],
...
}
What's the best way to achieve this without mutating groups
and currentGroup
, in a purely functional way? Do I need to take a harder look at Array.reduce
, because I've seen some (IMHO rather mind-boggling) use-cases to transform an Array into an Object, or is that not going to help here?
在没有以纯函数方式改变组和currentGroup的情况下实现这一目标的最佳方法是什么?我是否需要更加努力地看看Array.reduce,因为我已经看到一些(恕我直言,相当令人难以置信)的用例将一个数组转换为一个对象,或者这对我们没有帮助?
1 个解决方案
#1
2
Yes, you'd want to use reduce
here:
是的,你想在这里使用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
However, there is no reasonable way in JS to create a map object without mutation. As long as you keep your property assignments local, there's nothing wrong with that.
但是,JS没有合理的方法来创建没有变异的地图对象。只要您将财产分配保持在本地,就没有任何问题。
#1
2
Yes, you'd want to use reduce
here:
是的,你想在这里使用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
However, there is no reasonable way in JS to create a map object without mutation. As long as you keep your property assignments local, there's nothing wrong with that.
但是,JS没有合理的方法来创建没有变异的地图对象。只要您将财产分配保持在本地,就没有任何问题。