![](/img/trans.png)
[英]Javascript - flatMap method over array - (flatMap is not a function)
[英]How to get accumulator in flatMap array methode in JavaScript(flatmap vs reduce)?
有一个初始数组需要同时映射和过滤:
let data = [
{
"id": 1,
"parentId": null,
"dxId": "1_id",
"dxParentId": null,
"defName": "group1"
},
{
"id": 12,
"parentId": null,
"dxId": "12_id",
"dxParentId": null,
"defName": "группа3"
},
{
"id": 8,
"parentId": 1,
"dxId": "1_id/13",
"dxParentId": "1_id",
"defName": "group4"
},
{
"id": 5,
"parentId": 1,
"dxId": "1_id/20",
"dxParentId": "1_id",
"defName": "user1"
},
{
"id": 5,
"parentId": 1,
"dxId": "1_id/20",
"dxParentId": "12_id",
"defName": "user1"
},
];
我通过 parentide 属性的存在进行过滤,并收集结果字符串数组(不是初始对象数组)。
最初我是通过reduce方法做到的:
resultArr = data.reduce((filtered, obj) => {
if( obj.dx_parentId !== null) {
if(!(filtered.includes(obj.dxParentId))) {
filtered.push(obj.dxParentId);
}
}
return filtered;
}, []);
console.log(resultArr , 'result'); // ['1_id', '12_id'] 'result'
然后我自己发现这可以用 flatMap 数组方法来完成
resultArr = data.flatMap((obj) => obj.dxParentId !== null ? [obj.dxParentId] : []);
console.log(resultArr , 'result'); //['1_id', '1_id', '12_id'] 'result'
如果您注意到在减少的情况下我使用过滤(累加数组) ,我会使用包含进行额外检查,我会得到我需要的结果。
问题是如何通过 flatMap 做同样的事情? 是否可以在每次迭代时访问累积结果?
另外:有人可以告诉我在优化方面用什么更好地解决这种情况? mb forEach? 提前致谢
您无法访问在flatMap
中构建的数组。 在映射以及带扁平化的映射中,回调应该返回一个仅取决于特定项目的值。
对于这样的命令式算法,您可能根本不想使用reduce
:
const resultArr = [];
for (const obj of data) {
if (obj.dxParentId !== null) {
if (!resultArr.includes(obj.dxParentId)) {
filtered.push(obj.dxParentId);
}
}
}
console.log(resultArr, 'result');
但是,要从数组中获取唯一值,有一种更好(更简单、更有效)的方法:
const resultArr = Array.from(new Set(data.map(obj => obj.dxParentId).filter(id => id !== null)));
console.log(resultArr, 'result');
因此,虽然您无法在构建阵列平面图时查看它正在构建,但您可以在平面图之外创建一个 object 并使用它来跟踪您添加或未添加的 id。
const seen = {};
const resultArr = data.flatMap((obj) => {
const id = obj.dxParentId;
if (id in seen) return [];
if (id !== null) {
seen[id] = true;
return [id];
}
return [];
});
console.log(resultArr, "result"); //['1_id', '1_id', '12_id'] 'result'
就时间和空间复杂性而言,此解决方案要快得多,但占用更多空间(在大多数情况下这是一个很好的权衡)。
Array.include() 遍历整个数组,时间复杂度为 O(n)。 object 中的关键具有恒定的时间复杂度,但构建 object 是 O(n) 空间。
在我看来,最好的解决方案是将 object 的即时查找与 reduce 的范围相结合。
const resultArr = data.reduce(
(acc, obj) => {
const id = obj.dxParentId;
const { seen, filtered } = acc;
if (id in seen) return acc;
if (id !== null) {
seen[id] = true;
filtered.push(id);
}
return acc;
},
{ seen: {}, filtered: [] }
).filtered;
console.log(resultArr, "result"); // ['1_id', '12_id'] 'result'
此解决方案具有与平面图相同的时间和空间复杂性,但看到的 object 在 reduce 方法完成后就可以进行垃圾收集,因此这些潜在的空间问题并不那么重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.