如何展平对象属性数组有数组有javascript(es6)中的数组?

时间:2018-06-18 17:06:55

标签: javascript ecmascript-6 mapreduce

给出一个树形物体:

  • 用户有很多角色。
  • a Role有许多PermissionCollections
  • PermissionCollection有很多权限

你如何用javascript来平衡这一点以获得一系列权限

类似的东西:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "iconCell", for: indexPath) as! IconCollectionViewCell
        cell.iconImage.image = UIImage(named:iconSet[indexPath.row])

         if arrIndex.contains(indexPath.item) {
               cell.backgroundColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 0.3)

          }
          else {
                cell.backgroundColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 0.0)

          }
        return cell

    }

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

     if !arrIndex.contains(indexPath.item) {
        arrIndex.append(indexPath.item)
        collectionview.reloadData()

     }
 }

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
       if arrIndex.contains(indexPath.item) {
            arrIndex = arrIndex.filter { $0 != indexPath.item }
            collectionview.reloadData()
         }
    }

这是一个经典的地图减少问题吗?

2 个答案:

答案 0 :(得分:2)

这是一个(浅)扁平功能:

var flatten = array => array.reduce( ( a, b ) => a.concat( b ), [] );

您可以像这样申请。

var permissionGroups = flatten( user.roles.map( r => r.permissionGroups ) );
var permissions = flatten( permissionGroups.map( pg => pg.permissions ) );

答案 1 :(得分:2)

您认为reduce()可能会提供最干净的方法。

您可以concat()组合数组:

const allPermissions = user.roles.reduce((r, role) => 
  r.concat(role.permissionGroups.reduce((r, group) => 
    r.concat(group.permission), []), 
  []);

请注意,实际上每次返回时都会创建一个新数组,因此如果有很多角色,则可能效率低一些。要在不创建新数组的情况下执行此操作,您可以使用push.apply()代替:

const allPermissions = user.roles.reduce((r, role) => 
  r.push.apply(r, role.permissisionGroups.reduce((r, group) => 
    r.push.apply(r, group.permissions), []), 
  []);

使用apply()将允许您传递权限作为参数(基本上与调用push()很多相同)。如果您尝试推送数组,它会将其作为数组而不是单个值推送。

如果你想更进一步并且一直保留一个数组,你可以使用:

const allPermissions = [];    user.roles.forEach(role =>      role.permissionGroups.forEach(group =>        allPermissions.push.apply(allPermissions,group.permissions)      )    )

这基本上仍然是reduce()模式,但不会创建大量额外值。如果您想使用reduce(),它可能如下所示:

const allPermissions = user.roles.reduce((r, role) =>
  r.push.apply(r, role.permissionGroups.reduce((r, group) =>
    r.push.apply(r, group.permissions)), r), 
  []
);