0

I have three for loop as below to integrate their objects.
The problem is the length of 'cars' array is 20,000.
So it should runs every 20,000 times for finding same id between company.user and cars.
But the id of cars is unique.
Can I reduce this repeat number in JS? I want to reduce the taking time.
Thank you for reading it.

p.s. I uploaded same question adding the concrete logic inside of for loop.

for (let i = 0; i < company.length; i += 1) {
  for (let j = 0; j < company[i].user.length; j += 1) {
    for (let k = 0; k < cars.length; k += 1) {
      if (company[i].user[j].id === cars[k].id) {
        company[i].user[j] = {
          ...company[i].user[j],
          ...cars[k] 
        }
      }
    }
  }
}
13
  • is it possible to have multiple company.user and cars or is there only 1 match? Commented May 29, 2020 at 11:50
  • @Ifaruki It matches with only one thing.. Commented May 29, 2020 at 11:51
  • 1
    if its possible, you could sort the "cars" array and then use some search algorithms to reduce the search time. Everyhing you need to know about search algorithms you can find here geeksforgeeks.org/searching-algorithms Commented May 29, 2020 at 11:51
  • 1
    Don't check the length in the for loop, store the length and check against the stored value instead. stackoverflow.com/questions/8452317/… Commented May 29, 2020 at 11:57
  • @ThomasJason did the break improved something? Commented May 29, 2020 at 12:04

3 Answers 3

1

If there is only 1 match then use break after you found that item. Imagine you find that item at index 1 for example, then the loop would still continue and do 19998 loops. Because of the information that you know there is only 1 possible match you can break it there.

    if (company[i].user[j].id === cars[k].id) {
      company[i].user[j] = {
        ...company[i].user[j],
        ...cars[k] 
      }
      break;
    }
Sign up to request clarification or add additional context in comments.

Comments

0
 for (let i = 0, leni = company.length;; i < leni ; i += 1) {
    for (let j = 0, lenj = company[i].user.length; j < lenj; j += 1) {
      for (let k = 0, lenk = cars.length; k < lenk; k += 1) {
        if (company[i].user[j].id === cars[k].id) {
          company[i].user[j] = {
            ...company[i].user[j],
            ...cars[k] 
          }
          break; // match only the first one, then stop searching for cars
        }
      }
    }
  }

Answer based on test results from https://jsperf.com/caching-array-length/4

Spread left in base on

https://thecodebarbarian.com/object-assign-vs-object-spread.html

enter image description here

1 Comment

throw in an empty object but company[i].user[j] is not empty...
0

this will optimize your code a little more, but ziga1337 is right, the only effective way is to sort your two objects

// company: [ { user: [ { id: '?1' 
// cars: [ { id: '?2' 

for (let iCompagny of compagny) {
  for (let iUser of iCompagny.user) {
    let fCar = cars.find(xCar.id===iUser.id)
    if (fCar) Object.assign(iUser, fCar)
  }
}   

in case there is always a car.id unique to each user.id:

let indexCars = cars.reduce((a,c)=>{ a[c.id]=c; return a },{})

compagny.forEach(iCompagny=>{
  iCompagny.user.forEach(iUser=>{ Object.assign(iUser, indexCars[iUser.id]) })
})

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.