Ravi K
Ravi K

Reputation: 125

Map input array and get filtered array of object as result

I have below data coming from the backend.

priorities: [ 'get license', 'enroll college' ];

Now, I have a list of objects hardcoded at the front end.

studentPriorities = [
  { 
   prioritiesTitle: "get license",
   prioritiesDescription: "go to DMV and get your license"
  },
  {
   prioritiesTitle: "enroll college",
   prioritiesDescription: "gather fees and enroll for college"
  },
  {
   prioritiesTitle: "give exams",
   prioritiesDescription: "study hard for the exams"
  }
]

At any given time, I will get 2 priorities as a backend response. I need to search my hardcoded array of objects and get final data as follows.

mappedStudentPriorities = [
  { 
   prioritiesTitle: "get license",
   prioritiesDescription: "go to DMV and get your license"
  },
  {
   prioritiesTitle: "enroll college",
   prioritiesDescription: "gather fees and enroll for college"
  }
]

Can someone please suggest me how to achieve this?

Upvotes: 1

Views: 112

Answers (3)

Kilian Kilmister
Kilian Kilmister

Reputation: 364

You could use Array.prototype.flatMap on the array you get from the backend and then use Array.prototype.filter on the data entries. A function could look like this:

/** @param {string[]} priorities the titles you want to match */
function filterByPriorities (...priorities) {
  return priorities.flatMap(priority => studentPriorities.filter(({ prioritiesTitle }) => prioritiesTitle === priority))
}

The basic logic is:

  • for each string in input
    • filter the dataset for all elements where:
      • prioritiesTitle matches input
  • flatten the result of the previous operation
  • return the result

Now there isn't much advantage here, but if the data gets more complicated, using a for...of-loop is often a good idea. The function below will give the same result, but for complex operations, this tends to be easier to understand and maintain.

  • for each entry in dataset
    • if input includes entry title
      • push entry to out-array
  • return out-array
/** @param {string[]} priorities the titles you want to match */
function filter2 (...priorities) {
  const out = []
  for (const { prioritiesTitle, ...rest } of studentPriorities) {
    if (priorities.includes(prioritiesTitle)) out.push({ prioritiesTitle, ...rest })
  }
  return out
}

expected output for both is:

[
  {
    prioritiesTitle: 'get license',
    prioritiesDescription: 'go to DMV and get your license'
  },
  {
    prioritiesTitle: 'enroll college',
    prioritiesDescription: 'gather fees and enroll for college'
  }
]

About Array.prototype.includes

A decent junk of developers recommends using Array.prototype.indexOf instead of Array.prototype.includes because .includes isn't available in every browser ever made. But a few things are important to note on this:

  • every common browser* (including their counterparts for mobile) has had Array.prototype.includes for close to 5 years
  • depending on the engine, .indexOf for large data-sets can mean a massive speed penalty compared to .includes (from slightly slower if the item is at the end of the result, to a factor of 1000 times less operations/s in v8 (Chrome, nodejs etc) when the item is close to the start of the array. src)
  • unless you specifically have to support IE, there isn't much reason to not use .includes as the vast majority of users will use a browser that supports it.

*common browser -> browser with one of the usual JS-engines

  • v8 -> any Chromium based browser (Opera, Edge, Chrome)
  • spidermonkey -> FireFox
  • JavaScriptCore -> safari and allies

Upvotes: 2

Zain ul abideen
Zain ul abideen

Reputation: 146

I prefer to use indexOf because includes is not supported by old and some new browsers

const result = studentPriorities.filter(({ prioritiesTitle }) => (priorities.indexOf(prioritiesTitle) !== -1));

console.log(result);

Upvotes: 2

Derek Wang
Derek Wang

Reputation: 10194

This can be simply done using Array.filter & Array.includes.

Using Array.includes, you can check if the element is included in array or not and using Array.filter, you can get the filtered result which satisfies the condition.

const priorities = [ 'get license', 'enroll college' ];

const studentPriorities = [
  { 
   prioritiesTitle: "get license",
   prioritiesDescription: "go to DMV and get your license"
  },
  {
   prioritiesTitle: "enroll college",
   prioritiesDescription: "gather fees and enroll for college"
  },
  {
   prioritiesTitle: "give exams",
   prioritiesDescription: "study hard for the exams"
  }
];

const result = studentPriorities.filter(({ prioritiesTitle }) => priorities.includes(prioritiesTitle));
console.log(result);

Upvotes: 5

Related Questions