Is there a way to alter an array through a reference within a function?

I am working with a function that looks like this:

  public recursiveFilterLayers(node: LayerNode[]): LayerNode[] {
    const validItem = node.filter(
      (i) => i.visible === true || i.visible === undefined
    );

    validItem.forEach((i) => {
      if (i.children) i.children = this.recursiveFilterLayers(i.children);
    });

    return validItem;
  }

Then I call it using:

data = recursiveFilterLayers(data);

Is there a way to rewrite this function so that I don't have to use the return statement, like this:

recursiveFilterLayers(data);

In other words, how can I modify the function to directly manipulate the reference to the data array?

Answer №1

Array.filter creates a new array, meaning the original array remains unchanged. To modify the original array, you must manually iterate through it using a loop.

While using splice to delete elements may seem convenient, it has a time complexity of O(n²) because each removal requires shifting all subsequent elements back by one position.

An alternative method involves maintaining separate read and write indices, then executing a single splice operation at the end to truncate unnecessary elements:

function recursiveFilterLayers(node) {
  let readIndex;
  let writeIndex = 0;
  for (readIndex = 0; readIndex < node.length; readIndex++) {
    const element = node[readIndex];
    if (element.visible === true || element.visible === undefined) {
      node[writeIndex] = element;
      if (element.children) {
        recursiveFilterLayers(element.children);
      }
      writeIndex++;
    }
  }

  node.splice(writeIndex, readIndex - writeIndex);
}

const data = [
  {visible: true},
  {},
  {visible: false},
  {
    children: [{visible: false}, {visible: true}],
  },
];
recursiveFilterLayers(data);
console.log(data);

Answer №2

When working with javascript, it's important to understand that primitives are passed by value, while Objects are passed by a "copy of a reference." This means that functions can modify the content without needing to return anything.

If you're using a filter that simply copies the parameter's content, it won't actually modify anything. Instead, consider using the forEach method as shown below:

public recursiveFilterLayers(nodes: LayerNode[]): LayerNode[] {
    nodes.forEach(n=>{
        if((n.visible === true || n.visible === undefined) && n.children){
            this.recursiveFilterLayers(n.children);
        }
    });
    return;
}

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

Allow TypeScript in VSCode to locate files that do not contain a default export statement

To activate the Quick Fix feature for all files when encountering the error message 'Cannot find name 'myUtil'.ts(2304)', there is a need to tweak TypeScript settings. While TypeScript excels at recognizing files that have export defaul ...

Change the <base> element programmatically during server-side rendering

Searching for a way to obtain the base URL for an HTML page, so that relative URL requests from the browser utilize that base. If you are looking for answers, check out this link: Defining root of HTML in a folder within the site root folder When serving ...

Isn't it pointless to use try/catch/finally blocks together?

When working in languages like PHP and JavaScript, the finally {} block is designed to be executed after a try/catch block, regardless of whether an exception was thrown or not. However, one might argue that this is essentially the purpose of all code foll ...

Is there a way for me to display an http status code in my fetch error?

I created a React component where I am currently working on setting the state by making a network call. My goal is to eventually pass this state down to other child components, but for now, I am focused on getting everything connected properly. While atte ...

Designated router outlet showing empty content

I'm currently tackling a project in Angular where I find myself in need of two router outlets. The primary outlet is responsible for loading main pages and the dashboard page, while the secondary outlet, which I've dubbed "mainview", loads the co ...

Navigating IntelliSense Overload Signatures in VSCode

Searching for a solution in VSCode to navigate through multiple overload signatures in TypeScript and JavaScript? Occasionally, when using IntelliSense, a tooltip appears with hints like (+1 overload) while typing "someObj.someMethod(", displaying the fir ...

Angular navigation paths directing to incorrect components

For my blog application, I have set up separate routing modules for the admin and user sides. However, I am facing an issue where the client side routes are not being recognized after importing the routing module into app.module.ts. Instead of navigating t ...

The field 'updateEmployeeName' is not found in the 'ContactFormComponent' class

Just starting out with Angular and experimenting with Angular forms. Even though I followed a tutorial and copied the code below, I keep encountering the following error: Property 'updateEmployeeName' does not exist on type 'ContactFormCom ...

Exploring the World of Micro-Frontends with the Angular Framework

I am conducting research on the best methods for transitioning a large single-page application into a micro-frontend architecture. The concept: The page is made up of multiple components that function independently Each component is overseen by its own ...

Guide on displaying a grid in the center of the screen with a vertical sliding feature

I've noticed certain apps displaying a grid view or form on an alert box with vertical sliding, but I'm clueless about how to make it happen. As far as I know, this can be achieved using jQuery.. Any assistance would be greatly appreciated. Th ...

Guide on invoking child components' functions from the parent component in Angular 6

Main Component import { Component } from '@angular/core'; import { DisplayComponent } from './display.component'; @Component({ selector: 'my-app', template: ` <button (click)="submit()">Call Child Com ...

What steps can I take to address the issue with the jquery dropdown?

I am struggling with implementing JavaScript functionality on my website. Specifically, I have a dropdown menu in the hamburger menu that is causing some issues. Whenever I click on the services option, the dropdown opens but quickly closes again. I'v ...

Using TypeScript to effectively validate form checkboxes for input fields

I've created a form that includes multiple checkboxes with corresponding input fields. <div class="group-wrap input-element" id="gr_"> <div class="label-bar"> <label> <div class="cust ...

Verification of data using PHP, MySQL, and jQuery

I'm currently working on a process to extract data from an Excel file and then pass it on to a PHP file for validation against a database. If the data doesn't exist in the database, a message will be displayed to notify the user of incorrect data ...

jQuery Draggable Slider Scale

Seeking a draggable ruler (meaning it scrolls on double click) similar to the one showcased in the following link: I would greatly appreciate any assistance in finding a library that can provide this same functionality. View image here: https://i.sstatic ...

Iterating through images one time and capturing the mouse coordinates for every click made by the user

I have the following code snippet that displays a series of images and I would like to capture the coordinates of each mouse click on these images. Is there a way to send these coordinates to my email at the end of the image loop? Any assistance in achievi ...

Issue with the loading order of jQuery in Internet Explorer 9

My webpage heavily relies on jQuery for its functionality. While it works perfectly on most browsers, I am encountering issues specifically with IE9 due to the slow loading of JavaScript. The main problem lies in IE9 mistakenly thinking that JavaScript is ...

Determine if a dropdown menu includes a certain string within a designated group option

I have a specific condition in my code that states: "Add a new option if the select box does not already contain an identical option." Currently, a 'Hogwarts' option will only be added if there is no school with the same name already present. No ...

Upon initialization, navigate to the specified location in the route by scrolling

My page has various components stacked one after the other, such as: <about></about> <contact></contact> I am utilizing the ng2-page-scroll to smoothly scroll to a particular section when a navigation link is clicked. However, I a ...

Converting date string to a new format is not supported by moment js

Having some trouble with formatting dates for MySQL insertion. Here is the current HTML structure: <strong id="ut-open-date">27/06/2014</strong> I need to convert the date format to "YYYY-MM-DD" using moment.js library. My code snippet is as ...