9

How does one replace all elements of an array without losing references?

var arr = [1, 2, 3];
var b = arr;
b == arr; // true
magic(arr, [4, 5, 6]);
b == arr; // should return true

One way of doing it is by popping and pushing. Is there a clean way?

0

5 Answers 5

10

You could splice the old values and append the new values.

function magic(reference, array) {
    [].splice.apply(reference, [0, reference.length].concat(array));
}

var arr = [1, 2, 3],
    b = arr;

console.log(b === arr); // true
magic(arr, [4, 5, 6]);
console.log(b === arr); // should return true

console.log(arr);

Another way, is to use Object.assign. This requires to set the length of the array, if it is smaller than the original array.

function magic(reference, array) {
    Object.assign(reference, array, { length: array.length });
}

var arr = [1, 2, 3],
    b = arr;

console.log(b === arr); // true
magic(arr, [4, 5, 6, 7]);
console.log(b === arr); // should return true

console.log(arr);

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

5 Comments

Nothing questionable, it just makes me smile
@NinaScholz That seems like of a lot of work just to copy values from one array into another.
@NinaScholz: What's the advantage of that [].apply over something like reference.splice(0, reference.length, ...array) ? Is it just es5 compatibility?
@ScottSauyet, it is just the compatibility with ES5. with ES6, you could use spread syntax or the above mentioned Object.assign. acually the request needs a mutator function.
@torazaburo, some action is still required while keeping the reference, either lenght and push, splice or Object.assign.
3

The magic part could be:

arr.splice(0, arr.length, 4, 5, 6);

var arr = [1, 2, 3];
var b = arr;
b == arr; // true
arr.splice(0, arr.length, 4, 5, 6);
console.log(b);
console.log(arr);
console.log(arr === b);
.as-console-wrapper { max-height: 100% !important; top: 0; }

If you already have the replacing array in a variable (let's say repl = [4, 5, 6]), then use the rest parameters syntax:

arr.splice(0, arr.length, ...repl);

var arr = [1, 2, 3];
var b = arr;
var repl = [4, 5, 6];
b == arr; // true

arr.splice(0, arr.length, ...repl);
console.log(b);
console.log(arr);
console.log(arr === b);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

1

Here's one way:

var arr = [1, 2, 3];
var b = arr;
console.log(`b == arr, b
`, b == arr, b.join());
var c = magic(arr, [4, 5, 6]);
console.log(`b == arr, b
`, b == arr, b.join());
console.log(`c == arr, c
`, c == arr, c.join());

function magic(to, from) {
  // remove elements from existing array
  var old = to.splice(0);
  
  for (var i = 0; i < from.length; i++) {
    to[i] = from[i];
  }
  
  return old;
}

This implementation returns a copy of the old elements that were originally in the array.

Comments

0

Copy the new values over the old ones.

function magic(arr, newvals) {
  for (let i = 0; i < newvals.length; i++) arr[i] = newvals[i];
  arr.length = newvals.length;
}

Comments

0
function replaceArrValues(arrRef, newValues)
{
  arrRef.length = 0; // clear the array without losing reference
  newValues.forEach(x => arrRef.push(x));
}

2 Comments

This code-only answer could be improved with a little bit of written explanation. Especially: how does this compare to the splice technique others have contributed.
While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.

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.