如何检查数组树中的 parent 访问?

How to check parent access in an array tree?

我有一个无限数组树:

type Test = {
  id: string;
  hasAccess: Boolean;
  access: 'None' | 'View';
  children: Test[];
};

const Data: Test[] = [
  {
    id: '1',
    access: 'View',
    children: [
      {
        id: '2.1',
        access: 'None',
        children: [
          {
            id: '3.1',
            access: 'None',
            children: [
              { id: '4.1', access: 'None', children: [] },
              { id: '4.2', access: 'None', children: [] },
            ],
          },
        ],
      },
      {
        id: '2.2',
        access: 'View',
        children: [
          {
            id: '3.2',
            access: 'View',
            children: [],
          },
        ],
      },
    ],
  },
];

我想做的是根据 parent 的访问权限检查当前访问权限 - 除非有一种方法可以在数组树中检查 children 的访问权限。

所以如果我在 id: '2.1',我正在检查我对 id: '1' 的访问。

规则是,如果我的访问权限 === 'View',那么我的 hasAccess 布尔值将为真。如果我的访问权限 === 'None' 但我的 parent 的访问权限 ===“查看”,我的访问权限也将是真实的。

只有当我的访问权限 === "None" 和我的 parent 的访问权限 === "None" 时,我的 hasAccess 布尔值才会为假。

我有一个递归函数。但它并没有像我预期的那样工作。

const setParent = (Data, parentAccess) => ({
  ...Data,
  // checking condition here
  hasAccess: parentAccess === 'None' && Data.access === 'None' && false || true,
});

const setData = (Data: any[]) => {
  if (Data.length) {
    if (Data[0].children.length) {
      const currentAccess = Data[0].access;
      Data[0] = Data[0].children.map((data) => setParent(data, currentAccess));
    } else {
      Data.forEach(({ children }) => setData(children));
    }
  }
};

这是我的预期输出:

// id: '2.1' hasAccess: true because it's parent access === "View".
// id: '3.1' hasAccess: false because it's access === "None" and it's parent's access === "None".
// And all of id: '3.1' children hasAccess will be false.
const DataAfter: Test[] = [
  {
    id: '1',
    hasAccess: true,
    access: 'View',
    children: [
      {
        id: '2.1',
        hasAccess: true,
        access: 'None',
        children: [
          {
            id: '3.1',
            hasAccess: false,
            access: 'None',
            children: [
              { id: '4.1', hasAccess: false, access: 'None', children: [] },
              { id: '4.2', hasAccess: false, access: 'None', children: [] },
            ],
          },
        ],
      },
      {
        id: '2.2',
        hasAccess: true,
        access: 'View',
        children: [
          {
            id: '3.2',
            hasAccess: true,
            access: 'View',
            children: [],
          },
        ],
      },
    ],
  },
];

这个 hasAccess: parentAccess === 'None' && Data.access === 'None' && false || true, 将永远 return true。您可以使用三元运算符来解决这个问题。

此外,在递归方法中,您只为第一个数组项的所有子项设置 hasAccess。对于其他项目,您没有设置父项。

您可以执行以下操作,

const Data = [
  {
    id: '1',
    access: 'View',
    children: [
      {
        id: '2.1',
        access: 'None',
        children: [
          {
            id: '3.1',
            access: 'None',
            children: [
              { id: '4.1', access: 'None', children: [] },
              { id: '4.2', access: 'None', children: [] },
            ],
          },
        ],
      },
      {
        id: '2.2',
        access: 'View',
        children: [
          {
            id: '3.2',
            access: 'View',
            children: [],
          },
        ],
      },
    ],
  },
];


const setParent = (Data, parentAccess) => {
  return {
    hasAccess: parentAccess === 'None' && Data.access === 'None' ? false : true,
    ...Data,
  };
};

const setData = (dataItem, parentAccess = 'None') => {
      
      if(dataItem.children.length) {
        const currentAccess = dataItem.access;
        dataItem.children = dataItem.children.map(child => setData(child, currentAccess));
      } 
      
      dataItem = setParent(dataItem, parentAccess);
      return dataItem;
};
newData = Data.map(dataItem => setData(dataItem, dataItem.access))
console.log(newData);

您可以在一个函数中相当简单地完成此操作:

const setAccess = (xs, parent = null) =>
  xs .map (({id, access, children = []}) => ({
    id,
    hasAccess: (access != 'None' || (parent != null && parent != 'None')),
    access,
    children: setAccess (children, access)
  }))

const Data = [{id: '1', access: 'View', children: [{id: '2.1', access: 'None', children: [{id: '3.1', access: 'None', children: [{id: '4.1', access: 'None', children: []}, {id: '4.2', access: 'None', children: []}]}]}, {id: '2.2', access: 'View', children: [{id: '3.2', access: 'View', children: []}]}]}];

console .log (setAccess (Data))
.as-console-wrapper {max-height: 100% !important; top: 0}

唯一的复杂性与处理没有父节点的根节点有关。我们默认父级访问 null 并将明显的 (access != 'None' || parent != 'None') 替换为 (access != 'None' || (parent != null && parent != 'None')),使递归非常简单。