1

I've got an array with list of patients and they all have unique id.

 this.state = { 
  patients = [
        {id: "1", name: "Joe", age: 6, location: ''},
        {id: "12", name: "Her", age: 2, location: ''},
        {id: "1123", name: "Jin", age: 10, location: ''},
        {id: "11234", name: "Nick", age: 23, location: ''},
        {id: "12345", name: "Fil", age: 50, location: ''},
    ];

When a user clicks on a button it sends the paitient unique id, and location on a callback. I then use the unique id to find the patient in the patients array and update that patient's location. The way I find the patient in the array is using map to loop over the patients array, check if the patientId matches the id in the array and adds the location for that patient. However, map will always go over every patient in the patients array so does unnecessary looping & is expensive if the array gets bigger. I know there are other ways to find the element in the array i.e. findIndex() method but is it any better than the map? Whats the best approach for this use case?

 <Button 
    id={location} 
    onClick={() => addPatientLocation(patientId, location}
 > 
    {location}
</Button>

Function that check if patient id matched and updates that patients details

  addPatientLocation(patientId, location) {
        this.setState(prevState => ({

            patients: prevState.patients.map(p => {
                if (p.id === patientId) {
                    return { ...p, location: location };
                }
                return p;
            }),
        }));
    }
Jereme
  • 427
  • 7
  • 15
  • 1
    If you are using `find` operation multiple times after setting up your state. you can convert your array into an object having `patients = {id: }`. then each search will be of `O(1)` else you will have to go with a linear search. – AZ_ Mar 16 '20 at 10:37
  • Check this link for using Array.find() https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find and don't forget to check can I use to decide do you need polyfill or not – Drag13 Mar 16 '20 at 10:37
  • `locaiton` !== `location` – George Mar 16 '20 at 10:59

3 Answers3

2

My example makes use of findIndex. I benchmarked findIndex vs map function, see results below. The benchmark shows that findIndex is much faster.

var t1 = performance.now();
const patients = [
        {id: "1", name: "Joe", age: 6, locaiton: ''},
        {id: "12", name: "Her", age: 2, locaiton: ''},
        {id: "1123", name: "Jin", age: 10, locaiton: ''},
        {id: "11234", name: "Nick", age: 23, locaiton: ''},
        {id: "12345", name: "Fil", age: 50, locaiton: ''},
    ];
 
const index = patients.findIndex((elem) => elem.id =="11234");
patients[index].location="Location";
console.log(patients[index]);
var t2 = performance.now();   
console.log("time consumption", (t2 - t1));

var t1 = performance.now();
const patients = [
        {id: "1", name: "Joe", age: 6, locaiton: ''},
        {id: "12", name: "Her", age: 2, locaiton: ''},
        {id: "1123", name: "Jin", age: 10, locaiton: ''},
        {id: "11234", name: "Nick", age: 23, locaiton: ''},
        {id: "12345", name: "Fil", age: 50, locaiton: ''},
    ];
 
const obj = patients.map((elem, index) => {
  if (elem.id =="11234") {
    return { ...elem, locaiton: "Location" };
  }
  return elem;
});
console.log(obj[3]);
var t2 = performance.now();   
console.log("time consumption", (t2 - t1));
Tim
  • 10,459
  • 4
  • 36
  • 47
  • The results are not consistent time consumption 14.12999999593012 for using map time consumption 1.9949999987147748 for findIndex – muddassir Mar 16 '20 at 11:07
  • 1
    @muddassir if you run it several times, your result is being cached. But even if you run it several times (with reloading the page), findIndex is always faster than map! – Tim Mar 16 '20 at 11:07
1

You can use findIndex

let patients = [...this.state.patients]
let index = patients.findIndex(t=>t.id == patientId)
patients[index] = { ...patients[index], location: value }
this.setState({patients})
muddassir
  • 815
  • 9
  • 16
  • 1
    map constructs a new array while findIndex does not construct a new array https://stackoverflow.com/questions/55246694/performance-findindex-vs-array-prototype-map – muddassir Mar 16 '20 at 10:58
0

Can you use Map instead of Array ? It will get the patient by id faster.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

hugholousk
  • 159
  • 2
  • 9
  • @Andy I thought he worry about looping over entire array when the array getting bigger ( although that's quire not possible since the array hardly can reach to millions element to affect the performance of his code) – hugholousk Mar 16 '20 at 10:58