0

I have an array that contains objects with multiple values that could grow from hundreds to thousands of elements that need to be constantly accessed and modified. Something like:

var array = [
  {
    id: 'someId',
    val1: 'someValue',
    val2: 'someValue'
  },
  {...n}
] 

In order to change an existing object I'll get it by id while looping through the array

array.forEach(obj => {
  if(obj.id == '999'){
    obj.value2 = 'someOtherValue'
  }
})

I know there are different ways of looping and different methods, for, indexOf, find, etc, I'm not asking which is the best or efficient way, but it seems weird to iterate over a big array that many times.

So, is there another way I could alter a object at a certain location in the array without having to loop every time or it this normal ?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
RDU
  • 812
  • 1
  • 9
  • 22

2 Answers2

3

If you wanted to speed things up, you could use an Object rather than an Array.

E.g.

var obj = {
  someId: {
    val1: 'someValue',
    val2: 'someValue'
    }, ... 
}

This would be quicker as objects can be accessed/amended using obj.someId rather than looping.

Rob Bailey
  • 920
  • 1
  • 8
  • 23
1

First off, for loops are more performant than Iterable.forEach loops.

Secondly, what's stopping you from doing this?

const arr = [];

for (let i = 0; i < 5; i++) {
  arr.push({
    id: i,
    type: '',
    sound: 'Bark!'
  });
}
console.log(JSON.stringify(arr));
arr[2]['type'] = '';
arr[2]['sound'] = 'Oink!';
console.log(JSON.stringify(arr));

We can do this if we've got an array of objects that increase incrementally. Alright, but maybe we don't know what index it's in - or maybe, our list is unsorted.

let arr = [],
    names = ['Waffles', 'Pancake', 'Strawberry', 'Chocolate', 'Biscuit'];

for (let i = 0; i < 5; i++) {
  arr.push({
    id: i,
    name: names[i],
    type: '',
    sound: 'Bark!'
  });
}
console.log(JSON.stringify(arr));
arr = arr.map(animal => {
  if (animal.id !== 2) return animal;
  animal.type = '';
  animal.sound = 'Oink!';
  return animal;
});
console.log(JSON.stringify(arr));

That being said, to be even more performant, we should use a for loop. If time is very crucial for you, chances are you're dealing with a super large data set. In that case, I'd recommend switching over to key-value mapped storage: either as a JavaScript object, Sequalise file, Redis database (fast database using RAM) for fast retrieval, or MySQL/Postgres/MariaDB etc. (slightly slower, as it uses storage) for storing super large data sets.

let arr = [],
    names = ['Waffles', 'Pancake', 'Strawberry', 'Chocolate', 'Biscuit'];

for (let i = 0; i < 5; i++) {
  arr.push({
    id: i,
    name: names[i],
    type: '',
    sound: 'Bark!'
  });
}

console.log(JSON.stringify(arr));

// You could just start out with storing it as an object, however in this example I'm going to convert my previous array.
// It's best to only do this once, though. If you already have existing data and want to convert it over to an object, I'd recommend doing it like this.
const obj = {};

for (let i = 0; i < arr.length; i++) {
  const animal = arr[i];
  obj[animal.id] = animal;
}

console.log(JSON.stringify(obj));

obj[3]['type'] = '';
obj[3]['sound'] = 'Oink!';

console.log(JSON.stringify(obj));

// Now, let's convert it back. You probably will never need to do this, though, unless you REALLY need to use array iterators.
// You can always use a for loop with Object.keys(obj) if you ever need to use it as an iterator. Then, you can access properties of obj using obj[key].
console.log(JSON.stringify(Object.values(obj)));
PiggyPlex
  • 631
  • 1
  • 4
  • 15