0

I need to obtain a few values from a MAP in JS based on its id ("codi" in the object).

My array is something like this but bigger:

0: {codi: '291', literal: 'MEDIFIATC Progres 2010 ', check: true}
1: {codi: '292', literal: 'MEDIFIATC Progres < 2010 ', check: true}
2: {codi: '293', literal: 'MEDIFIATC Progres ', check: true}
3: {codi: '294', literal: 'MEDIFIATC Progres 2013  ', check: true}
4: {codi: '295', literal: 'MEDIFIATC Progres 2014 ', check: true}
5: {codi: '296', literal: 'MEDIFIATC MEDIFIATC  ', check: true}
6: {codi: '297', literal: 'MEDIFIATC MEDIFIATC P5 ', check: true}
7: {codi: '298', literal: 'MEDIFIATC MEDIFIATC P15 ', check: true}
8: {codi: '299', literal: 'MEDIFIATC MEDIFIATC DIAGONAL ', check: true}

Currently I am working on a simple loop, I iterate an when my variable is equals to the "codi" and return the entry.

function obtenerSubgrupo(codi) {
    for(j = 0; j < Object.keys(listaSubgrupo).length; j++) {
        if (codi == listaSubgrupo[i].codi) {
                return listaSubgrupo[i];
        }
    }   
}

How can I improve this?

I also need to extract the values that i am going to return from my main array, currently working with the info of: How can I remove a specific item from an array? but any help on that will be welcome too

Thanks.

EDIT: Just to put here the links shared by Simone Rossaini in the comments as i think they are quite useful:

https://javascript.plainenglish.io/are-for-loops-better-than-arrays-filter-or-foreach-methods-f54b6880d201

https://www.measurethat.net/Benchmarks/Show/4261/0/find-vs-forof-vs-for-loop

Grismak
  • 192
  • 16
  • 1
    You could use the filter method? Do something like data.filter((item) => return item.codi === '298'). Which would return an array with only one item in it (the one with codi 298, if the codi is unique of course.) If no matches and empty array would be returned. – JohnDoe Jul 25 '22 at 07:15
  • 1
    For-loop is faster than filter method so your code is correct and faster, take a look [here](https://javascript.plainenglish.io/are-for-loops-better-than-arrays-filter-or-foreach-methods-f54b6880d201) – Simone Rossaini Jul 25 '22 at 07:15
  • Thanks, great info for both of you, that article is nuts! i will still look the filter methods because i am quite ignorant about them but i will still work with the for loop. Again, thank you – Grismak Jul 25 '22 at 07:21

4 Answers4

4

Optimal would be to invest in changing the object to a map from the codi to the actual value. Afterwards any other extraction would be O(1).

var obj = {
  0: {codi: '291', literal: 'MEDIFIATC Progres 2010 ', check: true},
  1: {codi: '292', literal: 'MEDIFIATC Progres < 2010 ', check: true},
  2: {codi: '293', literal: 'MEDIFIATC Progres ', check: true},
  3: {codi: '294', literal: 'MEDIFIATC Progres 2013  ', check: true},
  4: {codi: '295', literal: 'MEDIFIATC Progres 2014 ', check: true},
  5: {codi: '296', literal: 'MEDIFIATC MEDIFIATC  ', check: true},
  6: {codi: '297', literal: 'MEDIFIATC MEDIFIATC P5 ', check: true},
  7: {codi: '298', literal: 'MEDIFIATC MEDIFIATC P15 ', check: true},
  8: {codi: '299', literal: 'MEDIFIATC MEDIFIATC DIAGONAL ', check: true}
}

// turning the input into an array
// skip if already an array
var arr = Object.values(obj)

var result = arr.reduce(function(agg,item) {
  agg[item.codi] = item;
  return agg;
}, {})

console.log(result);
// now you can:
console.log(result["294"]);
IT goldman
  • 14,885
  • 2
  • 14
  • 28
3

By "optimal" if you mean the most performant you should do benchmarks, and even then there can be differences in different browsers and run-time environments.

You can use more recent array methods in JS like find, keep in mind that filter will be definitively slower because it keeps iterating even when it finds the first match because searching for more matches.

item = listaSubgrupo.find(i => i.codi === codi)
Positivity
  • 5,406
  • 6
  • 41
  • 61
  • 1
    Seems like for-loop is faster then all method (same for find) [Bench](https://www.measurethat.net/Benchmarks/Show/4261/0/find-vs-forof-vs-for-loop) – Simone Rossaini Jul 25 '22 at 07:25
  • 1
    @SimoneRossaini thanks for the link, so the `for ... of` is the fastest according to this bench, right? can this website test on different browsers as well? – Positivity Jul 25 '22 at 07:30
  • 2
    `For.. of` is faster yes, For browsers I think you have to open them one by one even though I honestly don't think there are big differences. – Simone Rossaini Jul 25 '22 at 07:35
  • 1
    Yes, `for..of` is faster since it doesn't need to create a callback and a new context for each iteration. It's independent of the used method: as much as there's a callback it will be slower – Christian Vincenzo Traina Jul 26 '22 at 08:40
1

Assuming the codi values are unique convert the array to a Map or an object using the codi value as the key. It makes it simple to get at the data then.

This old question/set of answers re the value of which structure to use will be very helpful on deciding which to use.

Map:

const arr=[{codi:"291",literal:"MEDIFIATC Progres 2010 ",check:!0},{codi:"292",literal:"MEDIFIATC Progres < 2010 ",check:!0},{codi:"293",literal:"MEDIFIATC Progres ",check:!0},{codi:"294",literal:"MEDIFIATC Progres 2013  ",check:!0},{codi:"295",literal:"MEDIFIATC Progres 2014 ",check:!0},{codi:"296",literal:"MEDIFIATC MEDIFIATC  ",check:!0},{codi:"297",literal:"MEDIFIATC MEDIFIATC P5 ",check:!0},{codi:"298",literal:"MEDIFIATC MEDIFIATC P15 ",check:!0},{codi:"299",literal:"MEDIFIATC MEDIFIATC DIAGONAL ",check:!0}];

const map = new Map();

for (const obj of arr) {
  map.set(obj.codi, obj);
}

console.log(map.get('298'));

Object:

const arr=[{codi:"291",literal:"MEDIFIATC Progres 2010 ",check:!0},{codi:"292",literal:"MEDIFIATC Progres < 2010 ",check:!0},{codi:"293",literal:"MEDIFIATC Progres ",check:!0},{codi:"294",literal:"MEDIFIATC Progres 2013  ",check:!0},{codi:"295",literal:"MEDIFIATC Progres 2014 ",check:!0},{codi:"296",literal:"MEDIFIATC MEDIFIATC  ",check:!0},{codi:"297",literal:"MEDIFIATC MEDIFIATC P5 ",check:!0},{codi:"298",literal:"MEDIFIATC MEDIFIATC P15 ",check:!0},{codi:"299",literal:"MEDIFIATC MEDIFIATC DIAGONAL ",check:!0}];

const out = {};

for (const obj of arr) {
  out[obj.codi] = obj;
}

console.log(out['298']);
Andy
  • 61,948
  • 13
  • 68
  • 95
-1

did you try to use array.filter or array.find, see more here > https://www.w3schools.com/jsref/jsref_find.asp and > https://www.w3schools.com/jsref/jsref_filter.asp you can write it inside your array.map function by using if function to filter them.