0

Possibly this question has already been asked and answered a thousand times but I couldn't find it. Sorry :(

For the concept I have the following array in javascript (I am depicting the worst case szenario here):

var array1 = [{id: 8, text: "lala"},/* a lot of elements in between,*/ {id: 79, text: "lolo"}]

Now I would like to replace the element that has currently the id: 79 with Object {randomProperty1: "lulu"}. I don't want to replace the array afterwards as I use it as a reactive property in a reactive system like vuejs, so it should stay stateful. So I can't do something like:

array1 = array1.map(obj=>obj.id===79?{randomProperty1: "lulu"}:obj);

My naive approach so far is to do something like this:

const elem = array1.find(obj=>obj.id===79);
const index = array1.indexOf(elem);
array1[index] = {randomProperty1: "lulu"}

But now as I understand I would have to go through my array twice. Considering I have a huge array doing this operation every time my mouse moves, and maybe also having to recompute my new Object I felt better if I went only one time through my array. In every other case this would clearly be and maybe still is premature optimization but I'm interested in this.

My dream approach would be something like this (in pseudocode):

const elem = array1.find(o=>o.id===79);
elem = {randomProperty1: "lulu"}

But this obviously doesn't work as it is now call-by-value and not call-by-reference anymore.

The last (a bit ugly) approach I came up with is to change my array entirely like so:

var array2 = [{obj: {id: 8, text: "lala"}},/* a lot of elements in between,*/ {obj: {id: 79, text: "lolo"}}];
const elem = array2.find(o=>o.obj.id===79);
elem.obj = {randomProperty1: "lulu"}

So in short: Is there a better way to do it?

PS: I don't know it the tag 'vue-reactivity fit's here' - I don't know if this is a thing in angular or react as I don't know anything about those. My question just arose from vue-reactivity but I thought it could be generalized.

4

3 回答 3

1

Use findIndex() instead of find()

const index = array1.findIndex(o => o.id === 79);
if (index > -1) {
    array1[index] = {randomProperty1: "lulu"};
}

BTW, shouldn't the new object have an id property?

于 2020-04-13T19:11:23.513 回答
0

You don't need to check if index is -1 or not. if it's -1, when you use your array, it won't show up, you can only access it when you use array1[-1], but if you just console log array1, it skip the -1 index

var array1 = [{id: 8, text: "lala"},{id: 9, text: "lela"},{id: 10, text: "lale"},{id: 11, text: "lalala"}, {id: 79, text: "lolo"}]

array1[array1.findIndex(obj => obj.id === 79)] = {randomProperty1: 'lulu'}

于 2020-04-13T19:26:23.883 回答
0

One trick I have used when performance is top priority is to store the data in an object with an array of numeric ids to keep track of everything.

Example similar to yours:

var arr = [
 { id: 1, text: 'aaa' },
 { id: 2, text: 'bbb' },
 { id: 3, text: 'ccc' },
 { id: 78, text: 'zzz' }
];

var lookup = arr.reduce((prev, next) => {
  prev[next.id] = next;
  prev.allIds.push(next.id);
  return prev;
}, { allIds: [] });

Now if you know the id you want to replace you don't need to loop at all

lookup[78] = { id: 78, text: 'new!' };

If you do want to loop through the array use the allIds property

lookup.allIds.forEach(x=> {
  let item = lookup[x];
  item.text = '';
});
于 2020-04-13T19:40:14.337 回答