titanlux619
titanlux619

Reputation: 65

Filter from Array of objects

I have a Vue.js web app that consumes data from an express.js API and shows the response array in a table. Each object of the array has unique id formed by Name_Version (for example P.90.001000-0004_2). The problem is that I need to show only the last version of each one. For example, if the API response is:

[{id: P.90.001000-0004_1}, {id: P.90.001000-0004_2}, {id: P.90.001000-0004_3}, {id: P.90.002222-0025_1}, {id: P.90.002222-0025_2}]

the result array to show in the table would be:

[{id: P.90.001000-0004_3}, {id: P.90.002222-0025_2}]

It's been impossible for me to achieve this result, can anyone please help me?

Upvotes: 1

Views: 75

Answers (2)

Kobe
Kobe

Reputation: 6446

You can use reduce to get the latest version, and then use Object.entries with map and join to put them back into format:

const arr = [{id: 'P.90.001000-0004_1'}, {id: 'P.90.001000-0004_2'}, {id: 'P.90.001000-0004_3'}, {id: 'P.90.002222-0025_1'}, {id: 'P.90.002222-0025_2'}]


const latest = arr.reduce((a, {id}) => {
  const [k,v] = id.split('_')
  a[k] = +v > (a[k] || 0) ? v : a[k]
  return a
}, {})

const output = Object.entries(latest).map(pair => ({ id: pair.join('_')}))

console.log(output)

If you need to keep the rest of the properties, you can use a map, and keep reference to the original object by index:

const arr = [{id: 'P.90.001000-0004_1'}, {id: 'P.90.001000-0004_2'}, {id: 'P.90.001000-0004_3'}, {id: 'P.90.002222-0025_1'}, {id: 'P.90.002222-0025_2'}]

const latest = arr.reduce((a, {id}, i) => {
  const [k,v] = id.split('_')
  if(!a.has(k) || +v > a.get(k)[0]) a.set(k, [+v, i])
  return a
}, new Map())

const output = [...latest.values()].map(([,i]) => arr[i])

console.log(output)

Upvotes: 2

Alberto Trindade Tavares
Alberto Trindade Tavares

Reputation: 10356

You can build an object that maps the portion of the id without the version to the entire object, and you can keep in this map only the latest version of each item:

const data = [{id: 'P.90.001000-0004_1'}, {id: 'P.90.001000-0004_2'}, {id: 'P.90.001000-0004_3'}, {id: 'P.90.002222-0025_1'}, {id: 'P.90.002222-0025_2'}];
const map = {};

data.forEach((item) => {
  const [id, version] = item.id.split('_');
  const latestItem = map[id];
  
  if (!latestItem || latestItem.id.split('_')[1] < version) {
    map[id] = item;
  }
});

const filteredData = Object.values(map);
console.log(filteredData);

Upvotes: 2

Related Questions