Home > Software design >  JS: Why all elements of an array seems to share the same reference point?
JS: Why all elements of an array seems to share the same reference point?

Time:06-10

Description of my code:

  1. The first function (makeVector) populates all elements of the vector puzzle ([]) with an element of the row vector ([2, 4, 1, 3]).
  2. The second function (permuteVector) is a function that creates a queue class from a vector and then shifts all elements by n elements to the left and then returns a modified input vector (puzzle).

Problem:

The problem is that (permuteVector) works perfectly if I iterate over nested array that is just declared like this: let test = [[3, 5, 3],[2, 6, 7],[10, 0, 9],[5, 4, 3, 2]]. In that case, I can change just one element of an array (for ex test[1]) without affecting all of the other elements. When I try to do the same with the puzzle array (as intended) created with (makeVector) I can not change a single element without affecting all of them.
Seems like all of the elements of the puzzle array have the same reference point. I would appreciate any hints.

  class Queue {
  constructor() {
    this.q = [];
  }
  enqueue(el) {
    this.q.push(el);
  }
  dequeue() {
    if (this.q.length > 0) {
      return this.q.shift();
    } else {
      return 'Underflow';
    }
  }
  isEmpty() {
    return this.q.length == 0;
  }
  head() {
    if (this.q.length > 0) {
      return this.q[0];
    } else {
      return 'Queue is empty';
    }
  }
  show() {
    return this.q;
  }
}
//
let row = [2, 4, 1, 3];
// let puzzle = [];
//
const makeVector = function (row, n) {
  let puzzle = [];
  for (let i = 0; i < n; i  ) {
    puzzle.push(row);
  }
  return puzzle;
};

// makeVector(row, 4);
let puzzle = makeVector(row, 4);
console.log(puzzle);
//
const permuteVector = function (row, p) {
  let q1 = new Queue();
  //1. Creating queue from a vector
  for (let i = 0; i < row.length; i  ) {
    q1.enqueue(row[i]);
  }
  //2. Shifting queue by p elements to the left
  for (let i = 0; i < p; i  ) {
    if (p == 0) {
      return row;
    } else {
      let head = q1.head();
      q1.enqueue(head);
      q1.dequeue(head);
    }
  }
  //3. Populating Queue to original Vector
  row.splice(0, row.length, ...q1.show());
};


// With this it works - I can shift single element of an array without affecting others

let test = [
  [3, 5, 3],
  [2, 6, 7],
  [10, 0, 9],
  [5, 4, 3, 2]
];
permuteRows(test[1], 2);

// This will not work as intended, it will affect all elements instead of one
permuteVector(puzzle[0], 1);

CodePudding user response:

The problem is that you are assigning to your puzzle the row, and that's passed by reference, so when you alter the row you are altering that reference (which is four times in your puzzle array). You should copy the value:

puzzle.push([...row]);

More info about JavaScript value and reference: https://www.geeksforgeeks.org/primitive-and-reference-value-in-javascript/

  • Related