如何过滤javascript对象数组

IT技术 javascript arrays reactjs
2021-05-07 06:47:03

我有两个数组。我正在使用 PubSidebar 过滤基于 groupKey。

let groupKey = ['oaDeal', 'Journals', 'Deposit'] 
   // This array of object will be filtering with groupKey
const PubSidebar = [
  {
    value: 'Dashboard',
    role: 'public',
  },
  {
    value: 'oaDeal',
    role: 'private',
    content: [
      {
        role: 'private',
        value: 'oaDeal',
      },
    ],
  },
  {
    value: 'Journals',
    role: 'public',
    content: [
      {
        role: 'private',
        value: 'Journals',
      },
      {
        role: 'private',
        value: 'Token',
      },
      {
        role: 'private',
        value: 'policy',
      },
      {
        role: 'private',
        value: 'Deposit',
      },
      { role: 'public', value: 'test' },
    ],
  },
]
// Here is my trying code. I am filtering PubSidebar
const res = PubSidebar.filter(x => {
  // when it's main outerloop role public or private and groupKey matched
  if (
    x.role === 'public' ||
    (x.role === 'private' && groupKey.includes(x.value))
  ) {
    // then if inner-array exist then inner array filtering
    if (x.content) {
      // inside content assign condition public or private and groupKey
      let tempX = x.content.filter(
        y =>
          y.role === 'public' ||
          (y.role === 'private' && groupKey.includes(y.value)) ||
          x.value === y.value
      )
      x.content = tempX
      console.log(tempX)
      return x
    } else {
      // Other wise give me a single object public
      console.log(x)
      return x
    }
  }



})

如果父值:期刊或存款或任何值或角色:公共,我将面临在内容数组中传递对象的问题。我必须基于groupKey.

如果 Journals 和 Deposits 存在,则在 content 数组中添加 Journals 和 Deposit 数据,包括公共数据。(三个对象)

如果 Journals 存在,则在包含公共数据(两个对象)的内容数组中添加 Journals 数据如果存在 Deposits ,则在包含公共数据(两个对象)的内容数组中添加 Deposits 数据

如果 GroupKey journals 与 pubsidebar 中的内容对象匹配,则为两个对象,我们将得到

{
    value: 'Journals',
    role: 'public',
    content: [
      {
        role: 'private',
        value: 'Journals',
      },
      { role: 'public', value: 'test' },
    ],
  }

如果 GroupKey Deposits 与 pubsidebar 中的内容对象匹配,则有两个对象

{
    value: 'Deposit',
    role: 'public',
    content: [
      {
        role: 'private',
        value: 'Deposit',
      },
      { role: 'public', value: 'test' },
    ],
  }

如果 GroupKey Journals and Deposits 与 pubsidebar 中的内容对象匹配,则为三个对象,

    {
        value: 'Deposit' || "Journals",
        role: 'public',
        content: [
{
            role: 'private',
            value: 'Journals',
          },
          {
            role: 'private',
            value: 'Deposit',
          },
          { role: 'public', value: 'test' },
        ],
      }
3个回答

您可以对任何深度进行过滤,然后重新组合对象以获得结果。

const
    filter = ({ content = [], ...o }) => {
        content = content.flatMap(filter);
        if (o.role !== 'public' && !groupKey.includes(o.value)) return [];
        return content.length ? { ...o, content } : o;
    },
    groupKey = ['oaDeal', 'Journals', 'Deposit'],
    pubSidebar = [{ value: 'Dashboard', role: 'public' }, { value: 'oaDeal', role: 'private', content: [{ role: 'private', value: 'oaDeal' }] }, { value: 'Journals', role: 'public', content: [{ role: 'private', value: 'Journals' }, { role: 'private', value: 'Token' }, { role: 'private', value: 'policy' }, { role: 'private', value: 'Deposit' }, { role: 'public', value: 'test' }] }],
    result = pubSidebar.flatMap(filter);

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

如果我理解正确,您想过滤 PubSidebar。如果它们具有公共角色或 groupKey 中包含的内容的值,则保留值。如果是这样,这将是您的功能:

PubSidebar.filter(x => (x.role === 'public' || groupKey.includes(x.value));

如果你也想在内容上运行它,我们可以把它拆开:

const filterByGroup = (x) => (x.role === 'public' || groupKey.includes(x.value));

let result = [];
for (let i = 0; i < PubSidebar.length; i++) {
  const item = PubSidebar[i];

  if (filterByGroup(item)) {
    if (item.content) {
      item.content = item.content.filter(filterByGroup);
    }
    result = [ ...result, item ];
  }
}

片段:

let groupKey = ['oaDeal', 'Journals', 'Deposit']
const PubSidebar = [{
    value: 'Dashboard',
    role: 'public',
  },
  {
    value: 'oaDeal',
    role: 'private',
    content: [{
      role: 'private',
      value: 'oaDeal',
    }, ],
  },
  {
    value: 'Journals',
    role: 'public',
    content: [{
        role: 'private',
        value: 'Journals',
      },
      {
        role: 'private',
        value: 'Token',
      },
      {
        role: 'private',
        value: 'policy',
      },
      {
        role: 'private',
        value: 'Deposit',
      },
      {
        role: 'public',
        value: 'test'
      },
    ],
  },
]

const filterByGroup = (x) => (x.role === 'public' || groupKey.includes(x.value));

let result = [];
for (let i = 0; i < PubSidebar.length; i++) {
  const item = PubSidebar[i];

  if (filterByGroup(item)) {
    if (item.content) {
      item.content = item.content.filter(filterByGroup);
    }
    result = [...result, item];
  }
}
console.log(result);

应用于filter数组项和每个项的内容。

const update = (data, keys) => {
  const publicOrGroup = ({ role, value }) =>
    role === "public" || keys.includes(value);

  return data.filter(publicOrGroup).map(({ content = [], ...item }) => ({
    ...item,
    content: content.filter(publicOrGroup)
  }));
};

const groupKey = ["oaDeal", "Journals", "Deposit"];
const PubSidebar = [
  {
    value: "Dashboard",
    role: "public"
  },
  {
    value: "oaDeal",
    role: "private",
    content: [
      {
        role: "private",
        value: "oaDeal"
      }
    ]
  },
  {
    value: "Journals",
    role: "public",
    content: [
      {
        role: "private",
        value: "Journals"
      },
      {
        role: "private",
        value: "Token"
      },
      {
        role: "private",
        value: "policy"
      },
      {
        role: "private",
        value: "Deposit"
      },
      {
        role: "public",
        value: "test"
      }
    ]
  }
];

console.log(update(PubSidebar, groupKey));