Delete an element from a nested JSON array by utilizing its Id/Key

My json structure simulates a folder setup as follows:

    {
    "boxId": "45345344535",
    "modifiedDate": "2023-08-18T11:07:43-04:00",
    "name": "FolderTest",
    "size": 7751630,
    "files": [
        {
            "boxId": "2343214243",
            "modifiedDate": null,
            "name": "Original Preprint Submission.pdf",
            "size": null
        },
        {
            "boxId": "43534534543534",
            "modifiedDate": null,
            "name": "Original Supporting docs.msg",
            "size": null
        }
    ],
    "folders": [
        {
            "boxId": "34534534534535",
            "modifiedDate": "2023-08-18T11:07:02-04:00",
            "name": "Round 1",
            "size": 4092614,
            "files": [
                {
                    "boxId": "45325252435235",
                    "modifiedDate": null,
                    "name": "Round 1 Preprint.pdf",
                    "size": null
                },
                {
                    "boxId": "45436567546754",
                    "modifiedDate": null,
                    "name": "Round 1 response.pdf",
                    "size": null
                },
                {
                    "boxId": "324243245435345",
                    "modifiedDate": null,
                    "name": "Round 1 supporting doc 1.pdf",
                    "size": null
                },
                {
                    "boxId": "3421342142142134",
                    "modifiedDate": null,
                    "name": "Round 1 supporting doc 2.docx",
                    "size": null
                }
            ],
            "folders": []
        }
    ]
}

I am attempting to devise a recursive function that can identify and remove a specific file node based on its id within the original array. I have come across a relevant discussion at this link, but adapting it to my json structure is proving challenging.

Answer №1

Get rid of IN-PLACE:

const removeNode = (parent, id) => {
  let idx = parent.files.findIndex(({boxId}) => id === boxId);
  if(idx >= 0){
    parent.files.splice(idx, 1);
    return true;
  }
  for(let i = 0; i < parent.folders.length; i++){
    if(parent.folders[i].boxId === id){
      parent.folders.splice(i, 1);
      return true;
    }
    if(removeNode(parent.folders[i], id)){
      return true;
    }
  }
  return false;
};

console.log('removing 3421342142142134:', removeNode(root, '3421342142142134'));
console.log(root);
<script>
const root = {
 
    "boxId": "45345344535",
    "modifiedDate": "2023-08-18T11:07:43-04:00",
    "name": "FolderTest",
    "size": 7751630,
    "files": [
        {
            "boxId": "2343214243",
            "modifiedDate": null,
            "name": "Original Preprint Submission.pdf",
            "size": null
        },
        {
            "boxId": "43534534543534",
            "modifiedDate": null,
            "name": "Original Supporting docs.msg",
            "size": null
        }
    ],
    "folders": [
        {
            "boxId": "34534534534535",
            "modifiedDate": "2023-08-18T11:07:02-04:00",
            "name": "Round 1",
            "size": 4092614,
            "files": [
                {
                    "boxId": "45325252435235",
                    "modifiedDate": null,
                    "name": "Round 1 Preprint.pdf",
                    "size": null
                },
                {
                    "boxId": "45436567546754",
                    "modifiedDate": null,
                    "name": "Round 1 response.pdf",
                    "size": null
                },
                {
                    "boxId": "324243245435345",
                    "modifiedDate": null,
                    "name": "Round 1 supporting doc 1.pdf",
                    "size": null
                },
                {
                    "boxId": "3421342142142134",
                    "modifiedDate": null,
                    "name": "Round 1 supporting doc 2.docx",
                    "size": null
                }
            ],
            "folders": []
        }
    ]
}
</script>

Answer №2

Just dive in with this helpful starting point -

function removeId({ files = [], folders = [], ...node }, id){
  return node.boxId === id
    ? []
    : [{ ...node, files: files.flatMap(f => removeId(f, id)), folders: folders.flatMap(f => removeId(f, id)) }]
}

Give it a whirl by running the demo on your local browser -

function removeId({ files = [], folders = [], ...node }, id){
  return node.boxId === id
    ? []
    : [{ ...node, files: files.flatMap(f => removeId(f, id)), folders: folders.flatMap(f => removeId(f, id)) }]
}

const node = {boxId: "45345344535",modifiedDate: "2023-08-18T11:07:43-04:00",name: "FolderTest",size: 7751630,files: [{boxId: "2343214243",modifiedDate: null,name: "Original Preprint Submission.pdf",size: null},{boxId: "43534534543534",modifiedDate: null,name: "Original Supporting docs.msg",size: null}],folders: [{boxId: "34534534534535",modifiedDate: "2023-08-18T11:07:02-04:00",name: "Round 1",size: 4092614,files: [{boxId: "45325252435235",modifiedDate: null,name: "Round 1 Preprint.pdf",size: null},{boxId: "45436567546754",modifiedDate: null,name: "Round 1 response.pdf",size: null},{boxId: "324243245435345",modifiedDate: null,name: "Round 1 supporting doc 1.pdf",size: null},{boxId: "3421342142142134",modifiedDate: null,name: "Round 1 supporting doc 2.docx",size: null}],folders: []}]}

console.log(removeId(node, "34534534534535"))
.as-console-wrapper { min-height: 100%; top: 0; }

[
  {
    "boxId": "45345344535",
    "modifiedDate": "2023-08-18T11:07:43-04:00",
    "name": "FolderTest",
    "size": 7751630,
    "files": [
      {
        "boxId": "2343214243",
        "modifiedDate": null,
        "name": "Original Preprint Submission.pdf",
        "size": null,
        "files": [],
        "folders": []
      },
      {
        "boxId": "43534534543534",
        "modifiedDate": null,
        "name": "Original Supporting docs.msg",
        "size": null,
        "files": [],
        "folders": []
      }
    ],
    "folders": []
  }
]

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

Anticipating the conclusion of a pending GET request

Currently, I am developing a system to create user accounts. There is a function in place that checks for the existence of a username and returns false if it doesn't exist. However, when another function calls this username checker, it automatically ...

Configuring route for serving static files in an Express server

I'm completely new to working with express, but I am eager to learn and follow the best practices. My goal is to serve files like CSS or index.html from a folder called 'public'. I have seen examples using .use and .get methods as shown belo ...

Initial React render fails to retrieve API data

I've encountered an issue during development where the page loads before the API data is sent. I attempted to use asynchronous functions, but it didn't resolve the problem as expected. I suspect that my approach may be incorrect. Here's a sn ...

When using node.js with express, the req.on('end') event is triggered, but the req.on('data') event does not fire

When using body parser, you have the option of either: application/x-www-form-urlencoded body parser or json body parser Both options yield the same results. This is how the API is being called: $.ajax({ type:'post', url:'/ ...

Having trouble with removing the disabled attribute from an input file submit button

Currently, I am in the process of validating the file size and extension before it gets uploaded. My code is almost functioning perfectly, but there seems to be an issue with removing the disabled attribute from the submit button when the file meets all th ...

The issue with the Hidden Content feature in the Slick Carousel is that it does not function correctly on the

There are some related topics worth exploring, such as: Slick carousel center class not working when going from last item to first item Despite trying various solutions, the issue still persists in my code. My goal is to have each item displayed in the ce ...

When the PHP function is invoked from JavaScript, no results are displayed

I need assistance with calling a PHP function from JavaScript. The goal is to call the PHP function and have it echo two arguments that are passed. However, the code I have written does not seem to be working as expected, as it does not print anything. Ca ...

What are the steps to reset a JavaScript game?

I'm currently working on a JavaScript game project. Once the game is finished, I'd like to give players the option to go back to the main menu by clicking a button, then start a new game by clicking play again. However, I've run into an issu ...

How can I match dates in order to run the following code?

If Purchase Date is after 31/Mar/xxxx it should not calculate elap_yend, rem_days, depre_cur, cur_wdv. Also I have to calculate GST with some options that is if SGST and CGST are chosen, I should not calculate IGST else if IGST selected or marked it shoul ...

Computed property not properly updating the v-if condition

RESOLVED: I have found a solution that almost solves the issue. By removing <div v-if="isFrameLoaded"> and binding the source data to <video>, the video now loads simultaneously with the request being sent. There is no data in getBLOB ...

Acquire the Information from a Textarea That Has Been Edited by the User

My challenge lies in taking user-entered text from a content editable textarea and sending it via POST request, but the fields edited by the user are returning with an empty textContent. The code snippet below shows that each .entryRow (obj) contains multi ...

Storing the results of an Ajax call in a global variable

What is the best way to store and access the output of an ajax call within a global variable? let globalOutput = []; $.ajax({ type: "GET", url: uri, dataType : "json", contentType: "application/json", data: { input: filterVa ...

Determine which children should be displayed in a Kendo treeview based on the field titled "ParentId"

After converting a list of records into JSON format, I am looking to transform this data into a hierarchical KendoTreeView. Here is the JSON data: [ { "id": 1, "name": "A", "parentID": 0, "hasItems": "true" }, { "id": 2, "name": "B", "parentID": 1, "has ...

Executing both JavaScript Promise .then() and .catch concurrently

I've been working on converting my WordPress comments into an ajax-driven system. Everything was going smoothly until I encountered a problem with the .catch() method triggering right after the .then() method. Below is the code snippet... Ajax engi ...

What is the process of creating JSON data using a string?

Can someone assist me with constructing JSON text as shown below? I am facing an issue where the variables like $token, $state, $failedServers are not being replaced with their actual values. I do not want to use any specific modules for this task, just lo ...

Observing rxjs Observable - loop through the results and exit when a certain condition is met / encountering an issue with reading property 'subscribe' of an undefined value

I'm fairly new to working with rxjs and I've been struggling to find the right operator for what I want to achieve. Here's my scenario - I have an array that needs to be populated with results from another observable. Once this array has en ...

How to properly cast interfaces when using Angular 4's HttpClient to fetch items

Here is the layout of my interface interface IPlacesResult { summary: { queryTime: number; // ... }; results: { id: string; // ... address: { streetNumber: number; // ... }; }[]; } To populate this interface, I ...

Transferring PHP objects to JavaScript arrays

I have been searching for a unique JS array of PHP arrays with a specific format. After hours of research and attempts to use the json_encode PHP function, I still haven't achieved the desired format. Here's an example of what I'm looking fo ...

Updating div with specific class based on selected values

I have utilized Angular to display content based on selected values from a dropdown menu. Now, I am seeking a solution to dynamically add a CSS class to a div when specific values are chosen. In other words, I want to apply certain styling to the div base ...

Is it possible to switch the background image when hovering?

Is the image proportion relevant to the issue at hand? <style> .img1:hover { background-image: url({%static 'images/img2.gif' %}); -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover; backg ...