Geethu Jose
Geethu Jose

Reputation: 1993

Filtering an array based on multiple arrays inputs

I have three arrays. 1. Existing viewers array - existingViewers

  1. New viewers array - newViewers

  2. Permitted Viewers array - permittedViewers

permittedViewers is used for rendering the drop-down. And I wish to filter the newViewers and existingViewers entries from the permittedViewers.

I am doing this as three steps. And I am afraid this is not the optimized way. Can someone suggest the ideal way of doing this? The expected result is

[
  {
    "id": 4,
    "name": "name4"
  },
  {
    "id": 5,
    "name": "name5"
  },
  {
    "id": 6,
    "name": "name6"
  }
]

let existingViewers = [{
      "viewerId": 1,
      "name": "name1"
    },
    {
      "viewerId": 2,
      "name": "name2"
    }
  ],
  newViewers = [

    {
      "viewerId": 3,
      "name": "name3"
    }
  ],
  permittedViewers = [{
      "id": 1,
      "name": "name1"
    },
    {
      "id": 2,
      "name": "name2"
    },
    {
      "id": 3,
      "name": "name3"
    },
    {
      "id": 4,
      "name": "name4"
    },
    {
      "id": 5,
      "name": "name5"
    },
    {
      "id": 6,
      "name": "name6"
    }
  ]
let grouped = [...existingViewers, ...newViewers]

let viewerFilter = grouped.map(viewer => { return viewer.viewerId; });

let filteredPermittedViewers = permittedViewers.filter(viewer => !viewerFilter.includes(viewer.id));

console.log(filteredPermittedViewers)

Upvotes: 3

Views: 137

Answers (2)

CertainPerformance
CertainPerformance

Reputation: 371069

I'd make a Set of the ids of the first two arrays, and then filter the third by whether the set includes the id. (Sets have O(1) lookup time)

let existingViewers=[{"viewerId":1,"name":"name1"},{"viewerId":2,"name":"name2"}],newViewers=[{"viewerId":3,"name":"name3"}],permittedViewers=[{"id":1,"name":"name1"},{"id":2,"name":"name2"},{"id":3,"name":"name3"},{"id":4,"name":"name4"},{"id":5,"name":"name5"},{"id":6,"name":"name6"}];

const ids = new Set([...existingViewers, ...newViewers].map(({ viewerId }) => viewerId));
const output = permittedViewers.filter(({ id }) => !ids.has(id));
console.log(output);

Upvotes: 4

i alarmed alien
i alarmed alien

Reputation: 9530

You can compress all three statements into a single statement -- just replace the variable name with the statement that creates it:

let existingViewers = [{
      "viewerId": 1,
      "name": "name1"
    },
    {
      "viewerId": 2,
      "name": "name2"
    }
  ],
  newViewers = [

    {
      "viewerId": 3,
      "name": "name3"
    }
  ],
  permittedViewers = [{
      "id": 1,
      "name": "name1"
    },
    {
      "id": 2,
      "name": "name2"
    },
    {
      "id": 3,
      "name": "name3"
    },
    {
      "id": 4,
      "name": "name4"
    },
    {
      "id": 5,
      "name": "name5"
    },
    {
      "id": 6,
      "name": "name6"
    }
  ]

let filteredPermittedViewers = permittedViewers.filter(viewer => ! [...existingViewers, ...newViewers].map(viewer => viewer.viewerId).includes(viewer.id));

console.log(filteredPermittedViewers)

Upvotes: 2

Related Questions