Javascript 按多个特性的无点编组

Javascript 按多个特性的无点编组,javascript,typescript,functional-programming,ramda.js,Javascript,Typescript,Functional Programming,Ramda.js,我正在努力实现一个变体groupBy,它允许以无点样式按多个属性分组。(我使用的是typescript和ramda) 我想根据从函数getProperties::A A->[b]返回的属性对一些类型为A的元素进行分组。在命令式范例中,实现可以如下所示: constgetproperties=(item:item):数组=>[item.x,item.y.z]; const groupByMany=(items:Item[]):Dictionary=>{ 让groupped:Dictionary={

我正在努力实现一个变体
groupBy
,它允许以无点样式按多个属性分组。(我使用的是typescript和ramda)

我想根据从函数
getProperties::A A->[b]
返回的属性对一些类型为
A
的元素进行分组。在命令式范例中,实现可以如下所示:

constgetproperties=(item:item):数组=>[item.x,item.y.z];
const groupByMany=(items:Item[]):Dictionary=>{
让groupped:Dictionary={};
对于(让项目中的项目){
for(让getProperties(项)的键){
如果(分组[键]){
分组[键]。推送(项);
}否则{
分组[键]=[项];
}
}
}
}
例如:

const items = [
  { i: 1, x: 'A', y: { z: 'B' } },
  { i: 2, x: 'A' },
  { i: 3, x: 'B', y: { z: 'B' } },
];
const expectedOutput = {
  A: [ { i: 1, ... }, { i: 2, ... }],
  B: [ { i: 1, ... }, { i: 3, ... }],
};
我会让你开始的-

constreduce=(f,init,xs)=>
xs.reduce(f,init)
常数upsert=(m,k,v)=>
m.has(k)
? m.得到(k).推(v)
:m.集(k,[v])
constgroupbymany=(f,xs)=>
减少
((m,x)=>
(f(x).forEach(k=>k&&upsert(m,k,x))
M
)
,新地图
,xs
)
常数项=
[{i:1,x:A',y:{z:B'}
,{i:2,x:'A'}
,{i:3,x:'B',y:{z:'B'}
]
常数结果=
群居
(item=>[item.x,item.y&&item.y.z]
,项目
)

console.log(Object.fromEntries(result.entries())
我无法从这个问题中判断您是否想要一些易于编写无点代码的东西,或者出于某种原因,您是否正在寻找实际的无点实现。如果是后者的话,恐怕这没有用。但这是一个相当简单的问题

constgroupbymany=(fn)=>(xs)=>
减少
((a,x)=>[…新集合(fn(x))]。减少
((a,k)=>k{…a[k]:[…(a[k]| |[]),x]}:a
A.
)
, {}
)
//const getProperties=(项)=>[path(['x'],项),path(['y','z'],项)]
const getProperties=juxt([path(['x']),path(['y','z']))
const items=[{i:1,x:A',y:{z:B'},{i:2,x:A'},{i:3,x:B',y:{z:B'}]
控制台日志
(groupByMany(getProperties)(项目)
)


const{juxt,path}=ramda
为什么它有“haskel”标记?您的示例实现抛出了一个错误:
uncaughttypeerror:在
{i:2,x:'A}上迭代时无法读取未定义的属性“z”