0

Say I want to replace an array of objects with an array of decorators:

var arr = [{id:1, text: "text1"}, {id:2, text: "text2"}, {id:3, text: "text3"}]; 

arr.forEach(function(el, idx){
  var newEl = new NewEl(el.id, el.text, arr[idx + 1], idx); 
  arr[idx] = newEl; 
}, this); 

console.log(arr); 

function NewEl(id, text, nextEl, idx){
  this.id = id; 
  this.text = text; 
  this.next = nextEl; 
} 

nextEl will still refer to the old object, not the next item in the array (whatever that element).
How do I pass a reference to the next element (location) in the array to the constructor function?

Note: If possible, I'd prefer not to use a workaround by modifying the logic within the loop (workaround involving setting 'next' on the previous element on next iteration).

Is it possible?

2
  • You can go from last to first. Commented May 15, 2016 at 4:11
  • @Qwerty I need both prev/next. Should have mentioned that though. Commented May 15, 2016 at 4:25

2 Answers 2

4

You can't use a reference before that reference is created (i'm sure that's obvious). So it is difficult to solve without changing the loop to look at the previous. However, if you must solve it without looking at the previously created items, you could change your NewEl to receive both the full array and next index instead of an actual reference. Something like the following:

function NewEl(id, text, arr, nextIndex){
    this.id = id; 
    this.text = text; 
    this.arr = arr;
    this.nextIndex = nextIndex; 
}

NewEl.prototype.getNext = function(){
    return this.arr[this.nextIndex];
}; 

The idea being that the only way you can use a reference prior to creating it, is to actual not use it, but store a way of accessing it later. However this is a terrible way of doing this, as any change to the array will break the getNext() function.

tldr; You should really just change the loop to reference the previous item, from the next iteration.

Sign up to request clarification or add additional context in comments.

3 Comments

Jup a getter would work. I thought indd about storing the current index instead of next, then use index+1 in the getter (this wouldn't break?). I agree with you that using the loop works, but it means that on every insert / delete, I'll have to modify the previous and next nodes. Not a problem though, just didn't seem very clean at first thought.
When you are building linked graphs you usually need to update link siblings on graph change events. It is clean.
Ok, then this is how I'll do it. Thanks!
1

You may do like this too

var arr = [{id:1, text: "text1"}, {id:2, text: "text2"}, {id:3, text: "text3"}];
arr.reduceRight((p,c) => (c.next = p,c));
arr.reduce((p,c) => (c.prev = p,c));

Since in one comment you mention you would like previous as well i added prev property too.

1 Comment

Yes, thanks for the suggestion. Since I have a tree structure with nested arrays of node objects I'll probably go the iterative way.

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.