What prevents the swapping of arrays within a 2D array using references?

In my coding project, I came across a Matrix stored in a 2D-array:

var testM = [
[0.0,2.0,3.0],
[1.0,1.0,1.0],
[7.0,5.0,6.0]
];

// execute row exchange between a and b
function swapRows(a,b){
  let temp = a.slice(); // Cloning the value directly rather than referencing
  a = b.slice();
  b = temp;
}

// When passing individual arrays:
swapRows(testM[0], testM[1]);

Despite running the code above, the original 2D array remains unchanged. Since I'm not well-versed in how JavaScript handles reference passing, any insight would be helpful. (It functions correctly when inserted inline, so it's puzzling why it doesn't work even with cloning by value)

UPDATE: I grasp the concept of swapping elements within a standard one-dimensional array; my interest lies more in understanding how JavaScript manages reference passing. (Not entirely sure if I'm using the correct terminology here).

Answer №1

The reason your code is not working is because when you assign to variables a and b inside the function, it does not change the references in the original table.

When you pass the function a reference to two internal arrays from the table, the function creates local variables a and b, each pointing to one of those references. Swapping a and b only changes which array reference the local variables point to, without affecting the original table. To modify the original table, you need a reference to the table itself so that you can swap what its array references point to - like this:

var testMatrix = [
    [0, 2, 3],
    [1, 1, 1],
    [7, 5, 6]
    ];
    
// Function to swap row a with b
function swapRows(table, a, b){
    [table[a], table[b]] = [table[b], table[a]]
}

// Pass in the table and indexes:
swapRows(testMatrix, 0, 1);
console.log(testMatrix)

If you insist on passing individual arrays, you could replace all values of one array with the other. However, this method is very inefficient:

var testMatrix = [
    [0, 2, 3],
    [1, 1, 1],
    [7, 5, 6]
    ];
    
// Function to swap row a with b
function swapRows(a,b){
    let temp = a.slice(); // Copy by value, not reference
    a.splice(0, a.length, ...b);
    b.splice(0, b.length, ...temp);
}

// Pass in the individual arrays:
swapRows(testMatrix[0], testMatrix[1]);
console.log(testMatrix)

Answer №2

Modify

You are unable to change a primitive (such as string, number, bigint, boolean, null, undefined, and symbol) because primitives are not mutable. (https://developer.mozilla.org/en-US/docs/Glossary/Primitive)

If you provide an array as a parameter, you can modify it within your function.


swapRows(testM, 0, 1);

function swapRows(arr,a,b){   // <-- arr = testM. The value is an ARRAY, therefore it can be changed (it's not a primitive) 
  let temp = arr[a].slice(); 
  arr[a] = arr[b].slice();
  arr[b] = temp;
}

Outdated

In JavaScript, you cannot pass a variable by reference. (This statement is incorrect. Refer to "Modify")

If you wish to manipulate an object, you can use one of these approaches:

  1. Assign a new value using a function that produces the computed value
  2. Modify the object (specific property of the object) by employing a method

Approach

You must provide the object (array) as an argument for the function

function swapRows(arr,a,b){
  let temp = arr[a].slice(); // Copy by value, not reference
  arr[a] = arr[b].slice();
  arr[b] = temp;
  return arr;
}

testM = swapRows(testM, 0, 1);

Technique

You have the option to expand the object or the prototype (note some precautions here: JavaScript: What dangers are in extending Array.prototype?)

Array.prototype.swapRows = function(a,b){
  let temp = this[a].slice(); // Copy by value, not reference
  this[a] = this[b].slice();
  this[b] = temp;
  return this;
}

testM.swapRows(0, 1);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Conceal or reveal input elements with a toggle function in jQuery by utilizing

When the user chooses an option from a dropdown list, I want to display or hide different input fields accordingly. I attempted to use toggle with boolean values, but it doesn't seem to be working as expected. I expect that if I send 'true' ...

Which JavaScript framework tackles the challenges of managing asynchronous flow, callbacks, and closures?

I have a strong aversion to JavaScript. I find it to be quite messy and disorganized as a language. However, I recognize that my lack of proficiency in coding with it may contribute to this perception. These past few days have been incredibly frustrating ...

Is it possible to pass an Array into a callback function in element-ui's el-autocomplete component?

I attempted to utilize the el-autocomplete tag in its simplest form: using an Array returned by a callback function (JSFiddle version). Vue.component('button-counter', { data: function() { return { selectdusers: [], user: &ap ...

Retrieve the data entered in the submit button field

My question concerns a form with two buttons: <form method="post" action=""> <button type="submit" name="age" value="20">Age 20</button> <button type="submit" name="age" value="30">Age 30</button> </form> When ...

The migration-mongo module is not being recognized as a standard CommonJS module

I have integrated a nodejs server component into my project, which includes the usage of migrate-mongo. In my package.json file, the type specified is module. However, when attempting to run the migration process, I encounter the following error: > migr ...

Warning: Unhandled promise rejection - The type error occurred because the property 'close' of the object is undefined

I am currently configuring node.js in order to test my JavaScript codes using the Jest JavaScript testing framework. Can anyone spot what I might have done incorrectly? package.json file { "name": "institute-jest", "version&quo ...

Greetings: Obtaining an array of text within the <td> tags

Here is the HTML Source: <td bgcolor="#ffffbb" colspan=2><font face="Verdana" size=1>2644-3/4<br>QPSK<br><font color="darkgreen">&nbsp;&nbsp;301</font> - 4864</td> I am looking to extract text array wit ...

Get the JSON file from Firebase storage

My query boils down to this: Within my vue.js application, I am uploading a json file to a firebase storage bucket. However, when attempting to download the file for use within the app, I encounter an "Uncaught (in promise) undefined" error. The goal is t ...

Troubleshooting ASP.NET MVC3: The mystery behind why my custom validation attributes always seem to fail

After completing several tutorials, I have successfully implemented my models from a library file (dll). Everything seems to be functioning correctly except for one issue. Here is my model: public class RoomBookingInsert { public Int32 CostCentreNo ...

Loop through a collection of arrays that contain the same elements, and multiply each consecutive element by a specified value x

I've been diving into a challenging problem involving remarkable numbers, which are defined as A number that is equal to the sum of all its proper divisors -- provided one of them is negative. For instance, the proper divisors of 12 are 1, 2, 3, 4, 6 ...

What is the origin of this MouseEvent attribute?

In my jsfiddle project, there is a white square that can be moved around by the mouse. When the mouse button is released, it displays the x and y coordinates of the square. To see the project in action, visit: http://jsfiddle.net/35z4J/115/ One part of t ...

Ajax cannot seem to come to a resolution

After completing my learning on Ajax, I decided to work on a simple project - a port scanner. However, I am facing issues with it as it is not working properly. The only message that pops up is 'Scan started' and I can't figure out what the ...

What issue is present in this Node.js one-line conditional statement?

Check it out: ( result.username === user.username ) ? res.status( 500 ).json( "That username is already taken." ) : res.status( 500 ).json( "That email has already been used." ) Shouldn't this execute the first part, res.status( 500 ).json( "That us ...

Unfortunately, CSS3 PIE is not compatible with border-radius and box-shadow properties

I created a basic HTML/CSS code for testing purposes, but I'm having trouble getting the library to function properly. I've placed the .htc, .php and .js files in the same directory as index.html, but it just won't work. Check out the code ...

Enhance your SVG progress circle by simply selecting checkboxes

I have a unique system with 5 checkboxes that act as a To-Do list. When I click on each checkbox, the circle's diameter should progressively fill up in increments of 1/5 until all 5 checkboxes are completed. The order in which the checkboxes are click ...

I want to know the process of increasing the id name of a div and the name of the content stored

I'm struggling to understand how to implement a for loop and increment multiple items. Can anyone offer guidance? Here's my jQuery code: var counter1 = localStorage.getItem('counter1item'); if (counter1 == null){ $("#i1").html(&ap ...

phpif (the current date is after a certain specific date, do

Can someone please help me solve this problem? I want to prevent echoing a variable if the date has already expired. Currently, my PHP code displays: Match 1 - April 1, 2015 Match 2 - April 8, 2015 What I need is for Match 1 to not be echoed if the cur ...

Clear Vuex state upon page refresh

In my mutation, I am updating the state as follows: try { const response = await axios.put('http://localhost:3000/api/mobile/v3/expense/vouchers/form_refresh', sendForm, { headers: { Accept: 'application/json', 'C ...

Button for PayPal Checkout

I am currently working on setting up a functional Paypal button for a personal e-commerce website. Everything runs smoothly in my sandbox testing environment, processing payments and returns without any issues. However, when I switch the client ID to the ...

Unable to compile relative path of threejs using browserify and babel

As a newcomer to babel and browserify, I encountered an issue while trying to transpile with browserify and babel. After installing the threejs package and adding the following import: import * as THREE from 'three' Everything worked fine when t ...