在javascript上使用flatmap,有条件

Posted

技术标签:

【中文标题】在javascript上使用flatmap,有条件【英文标题】:use flatmap on javascript, with condition 【发布时间】:2021-12-28 06:56:07 【问题描述】:

我正在创建一个处理监视和编辑权限的组件。 我用来保存权限的数据结构如下所示:

const input = [
    isAllowed: true,
    permissionType: "watch",
    userId: 14
  ,
  
    isAllowed: false,
    permissionType: "edit",
    userId: 14
  ,
  
    isAllowed: true,
    permissionType: "edit",
    userId: 24
  ,
  
    isAllowed: false,
    permissionType: "edit",
    userId: 34
  ,
  
    isAllowed: false,
    permissionType: "watch",
    userId: 44
  ,
  
    isAllowed: false,
    permissionType: "edit",
    userId: 44
  
]

一开始,我只是想获取所有具有任何权限的用户的列表,所以我会使用

let managers = _.flatMap(props.settings.managerPermissions, (p) => p.userId);
managers = [...new Set(managers)];

所以这会给我留下managers = [14,24,34,44],但我需要编辑这个平面图,这样我就不会找回根本没有权限的经理的 ID,即使他们已经添加到列表中,所以在这种情况下,新平面图的返回值应该是managers = [14,24]。 (当然 flatMap 在这里不是必须的,如果有更好的方法,我会很高兴看到它)

【问题讨论】:

在这种情况下“根本没有权限,”是什么意思?为什么是1424 @NinaScholz 我的意思是名单上的经理,但每次出现都是错误的。有 14 是因为它有查看权限,有 24 是因为它有编辑权限。 【参考方案1】:

只有当 map 的结果是数组的数组,而你想要一个平面数组时,你才需要 flatMap。

在这种情况下,通过isAllowed 过滤数组,然后映射到userId

const arr = ["isAllowed":true,"permissionType":"watch","userId":14,"isAllowed":false,"permissionType":"edit","userId":14,"isAllowed":true,"permissionType":"edit","userId":24,"isAllowed":false,"permissionType":"edit","userId":34,"isAllowed":false,"permissionType":"watch","userId":44,"isAllowed":false,"permissionType":"edit","userId":44]

const managers = [...new Set(
  arr
  .filter(o => o.isAllowed)
  .map(o => o.userId)
)]

console.log(managers)

但是,您实际上使用Array.flatMap()(或lodash 等效项)同时进行映射和过滤。地图/过滤器组合不太惯用,我不确定性能,所以我自己不使用它。这个想法是为您不想要的项目返回一个空数组:

const arr = ["isAllowed":true,"permissionType":"watch","userId":14,"isAllowed":false,"permissionType":"edit","userId":14,"isAllowed":true,"permissionType":"edit","userId":24,"isAllowed":false,"permissionType":"edit","userId":34,"isAllowed":false,"permissionType":"watch","userId":44,"isAllowed":false,"permissionType":"edit","userId":44]

const managers = [...new Set(
  arr.flatMap(o => o.isAllowed ? o.userId : [])
)]

console.log(managers)

【讨论】:

【参考方案2】:

您应该能够只过滤掉isAllowed=false,然后做同样的事情——尽管flatMap 似乎没用(因为没有数组嵌套)——只需使用map

const input = [
 isAllowed: true,
  permissionType: "watch",
  userId : 14
 ,
 isAllowed: false,
  permissionType: "edit",
  userId : 14
 ,
 isAllowed: true,
  permissionType: "edit",
  userId : 24
 ,
 isAllowed: false,
  permissionType: "edit",
  userId : 34
 ,
 isAllowed: false,
  permissionType: "watch",
  userId : 44
 ,
 isAllowed: false,
  permissionType: "edit",
  userId : 44
 ]
 
 const managers = [...new Set(input.filter(x => x.isAllowed).map(x => x.userId))];
 console.log(managers);

【讨论】:

x.isAllowed == true 真的吗? @NinaScholz 哈哈 - 傻。手指比大脑快 x.isAllowed === true 在这里实际上可能很有用,以防数据损坏(例如布尔字符串),因此默认情况下它假定没有权限。

以上是关于在javascript上使用flatmap,有条件的主要内容,如果未能解决你的问题,请参考以下文章

通过 if 条件从 `Array.flatMap()` 中不返回任何元素

javascript 中等flatMap示例

RxSwift:嵌套可观察对象上的 FlatMap

Typescript flatMap, flat, flatten 在任何类型上不存在 []

如何在 Flux<String> 上执行 flatMap() 时获取索引号

如何正确返回一个 void Observable?