-1

I have got two arrays . I am filtering based groupKey with PubSidebar.

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
    }
  }



})

I am facing problem to pass objects inside content array if parents value: Journals or Deposits or any value or role:pubic. I have to pass value inside content array based on groupKey.

If Journals and Deposits is existed , then adding Journals and Deposit data inside content array, including with public data . (three Objects)

If Journals is existed , then adding Journals data inside content array including with public data(two Objects) If Deposits is existed , then adding Deposits data inside content array including with public data(two Objects)

if GroupKey journals is matched with content object in pubsidebar then two objects , we will get

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

if GroupKey Deposits is matched with content object in pubsidebar then two objects

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

if GroupKey Journals and Deposits is matched with content object in pubsidebar then three objects ,

    {
        value: 'Deposit' || "Journals",
        role: 'public',
        content: [
{
            role: 'private',
            value: 'Journals',
          },
          {
            role: 'private',
            value: 'Deposit',
          },
          { role: 'public', value: 'test' },
        ],
      }
17
  • 1
    Expected output ??? Commented Apr 8, 2020 at 18:00
  • just edit , can you see Commented Apr 8, 2020 at 18:09
  • 1
    where is the difference? Commented Apr 8, 2020 at 18:11
  • I just want to pass Object inside content based groupKey . For example Deposits and Journals is matched with PubSidebar content Journals and Deposits then we got three objects including public one . if Deposits doesn't matched then deposit will be removed from pubsidebar Commented Apr 8, 2020 at 18:15
  • if GroupKey journals is matched with content object in pubsidebar then two objects , we got {value:"journals",role:"private} and { role: 'public', value: 'test' }, Commented Apr 8, 2020 at 18:17

3 Answers 3

2

You could take a filtering for any depth and reassemble the objects for the result.

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; }

Sign up to request clarification or add additional context in comments.

Comments

1

If I understand correctly you want to filter PubSidebar. Keeping values if they have a role of public or a value of whats included in the groupKey. If so this would be your function:

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

If you want to run that on content as well we could pull it apart:

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 ];
  }
}

Snippet:

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);

1 Comment

@sujon sure - added
1

apply filter on array items and on content of each item.

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));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.