2
\$\begingroup\$

I have two objects, one input = Array<Type> and one stored = Array<{..., Type}>

What's the best (cleanest) way to put the elements in the first array into the sub-elements of the second? We can assume they're of the same size.

My current code below works, but looks bad due to the double iterator usage.

var count = 0;
stored.forEach((obj)=> {
 obj.value = input[count];
 count++;
});

Is there some sort of prototyping that I can use to shorten the code up?

asked Feb 22, 2019 at 20:01
\$\endgroup\$
2
  • 1
    \$\begingroup\$ don't know if this qualifies as an answer but you don't need the count variable to increment the index, Array.forEach accepts a second ( optional ) parameter which is the current index that you can use : stored.forEach((obj, ndx) => { obj.value = input[ndx]; }); jsfiddle.net/qm6yep5r \$\endgroup\$ Commented Feb 22, 2019 at 20:49
  • \$\begingroup\$ @Taki That's exactly it. Thanks a lot! If you want to put it as an answer, I'll mark it. \$\endgroup\$ Commented Feb 22, 2019 at 20:53

2 Answers 2

1
\$\begingroup\$

You don't need the count variable to increment the index, Array.forEach accepts a second ( optional ) parameter which is the current index that you can use :

stored.forEach((obj, index) => { 
 obj.value = input[index]; 
});

OR

stored = stored.map((obj, index) => ({...obj, value: input[index]}))

example :

let stored = [{ name : 'a', value: 2 }, {name : 'b', value: 4 }, { name : 'c', value: 6 }];
let input = [10, 11, 12];
stored.forEach((obj, index) => { obj.value = input[index]; });
// OR
// stored = stored.map((obj, index) => ({...obj, value: input[index]}))
console.log(stored)

answered Feb 22, 2019 at 22:06
\$\endgroup\$
1
\$\begingroup\$

As the existing answer pointed out there is a index argument passed to the array iteration callbacks callback(item, idx, array)

Iterators

However you could also use an iterator

[Array.values()][1] returns an array iterator. You use iterator.next() to step over the items, and iterator.next().value to get an item.

That way you do not need an index and can use the more performant for of loop that does not have a ready idx.

const iterator = input.values();
for (const obj of stored) { obj.value = iterator.next().value }

However is works equally well in an array iteration function

const iterator = input.values();
stored.forEach(obj => obj.value = iterator.next().value)

Via a generator

You can also create a custom iterator using a generator function. For example say you wanted to reverse the input order.

function *reversed(array) { // NOTE the * signifies this is a generator 
 var i = array.length;
 while (i--) { yield array[i] }
}
var iterator = reversed(input); // create reverse iterator of input
for (const obj of stored) { obj.value = iterator.next().value }
// or
iterator = reversed(input); // restart reverse iterator of input
stored.forEach(obj => obj.value = iterator.next().value);

Note that the iteration assigning to store remained unchanged from above examples.

answered Feb 23, 2019 at 3:43
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.