3

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)

2
  • 2
    it looks like a codereview question, because the code is working. Commented Sep 13, 2018 at 8:51
  • I'm voting to close this question as off-topic because it should be on the Code Review SE site. Commented Sep 13, 2018 at 8:55

2 Answers 2

4

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

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

1 Comment

That will require constructing a new Set every single time an item is tested - better to construct the set in advance. For compactness, use a minifier
2

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)

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.