如何使用JavaScript中的函数编程从一对多列表构建反向映射?

如何使用JavaScript中的函数编程从一对多列表构建反向映射?,javascript,functional-programming,ramda.js,Javascript,Functional Programming,Ramda.js,我只是想澄清一下我所说的“倒转地图”的意思: const foo= {“a”:10 ,“b”:20 }; 康斯特福尤酒店= {“10”:“a” ,“20”:“b” }; 我有一个表示文件的对象: const文件= {id:100 ,标签:[20,30] }; 给定一个文件列表,我需要构建一个映射,该映射允许我查找具有给定标记的所有文件 由此: const文件= [{id:100] ,标签:[20,30] } ,{id:200 ,标签:[20,40] } ]; 为此: {“20”:{“10

我只是想澄清一下我所说的“倒转地图”的意思:

const foo=
{“a”:10
,“b”:20
};
康斯特福尤酒店=
{“10”:“a”
,“20”:“b”
};

我有一个表示文件的对象:

const文件=
{id:100
,标签:[20,30]
};
给定一个文件列表,我需要构建一个映射,该映射允许我查找具有给定标记的所有文件

由此:

const文件=
[{id:100]
,标签:[20,30]
}
,{id:200
,标签:[20,40]
}
];
为此:

{“20”:{“100”:1,“200”:1}
, "30": { "100": 1 }
, "40": { "200": 1 }
}
我最终得到了这个代码,它完成了这项工作:

const tag_file=(tag_id,file_id)=>({[tag_id]:{[file_id]:1});
const mergeDeepAll=reduce(mergeDeepRight,{});
const tag_map=compose(mergeDeepAll,lift(tag_文件));
const tags_map=compose(mergeDeepAll,map({id,tags})=>tag_map(tags,[id]);
标签和地图(文件);
//=> { "20": { "100": 1, "200": 1 }
//=> , "30": { "100": 1 }
//=> , "40": { "200": 1 }
//=> }

问题:我是否缺少任何函数式编程概念,这些概念可以让我更好地表达这一点?

不确定您为什么需要ramda,可以使用reduce和forEach来实现

const文件=[{
id:100,
标签:[20,30]
}, {
id:200,
标签:[20,40]
}];
//在数组上循环以生成对象
const result=files.reduce((对象,文件)=>{
//在标签上循环
file.tags.forEach(
标签=>
obj[tag]?//我们看到标签了吗?
obj[tag].push(file.id)://是
obj[tag]=[file.id]//否
)
return obj//返回reduce的对象
}, {})

console.log(result)
使用
Array.map()
idByTags
)创建一个函数,为每个对象生成成对的
[tag,id]
)。使用R.chain将所有对象转换为这样的对并展平它们。按标记(R.head)分组,然后映射对象(R.mapObjIndexed)并按id(R.last)计数:

const{pipe,chain,groupBy,head,mapObjIndexed,countBy,last}=R
const idByTags=({id,tags})=>tags.map(tag=>[tag,id])
常数fn=管道(
链(idByTags),
团长,,
mapObjIndexed(计数单位(最后))
)
const files=[{“id”:100,“tags”:[20,30]},{“id”:200,“tags”:[20,40]}]
const result=fn(文件)
console.log(结果)

哦,伙计,这太聪明了;)谢谢主要的问题是倒置,香草很容易,但我找不到任何拉姆达魔法能做到这一点。剩下的很明显。我会等着,以防有更多的答案,但这已经很好了!我找到了一种更简洁但仍然可读的方法,但是你的答案是最重要的。我只需要
chain
返回每个单独的映射,并最终将它们合并在一起:
pipe(chain({id,tags})=>tags.map(tag=>({[tag]:{[id]:1})),reduce(mergeDeepRight,{}))