Tips for locating a specific property deep within an array and pinpointing its exact location

Is it possible to use JavaScript to locate a property within an array that is nested within another array and return its "path"?

Visualize a hierarchical group of nested arrays similar to this example:

    var bigBox = [  

        mediumBoxA = [
                smallBoxA = [                  
                         toyA = { toyId : "Blue Ball"},
                         toyb = { toyId : "Pink Ball"}
                    ],

                smallBoxB = [                  
                         toyA = { toyId : "Girl Doll"},
                         toyB = { toyId : "Boy Doll"}
                    ],
            ],

        mediumBoxB = [
                smallBoxA = [                  
                         toyA = { toyId : "Batman"},
                         toyB = { toyId : "Superman"}
                    ],

                smallBoxB = [                  
                         toyA = { toyId : "Lego"},
                         toyB = { toyId : "Soldier"}
                    ],
            ]

   ];

With that setup, I aim to be able to search for something like "Batman" in the console and find out that it is located in bigBox > mediumBoxB > smallBoxA > toyA. I'm specifically looking for a solution using only JavaScript and one that can be executed in the console without involving HTML.

I understand that I could use index numbers instead of labels like "smallBox", "toyB", etc., but I included those labels for clarity purposes.

Appreciate your help!

Answer №1

I have created a recursive function that is capable of identifying the path and presenting it as an array:

/**
 * Locates a value and provides the path of nested variable names
 * 
 * @param {obj}       The object to be searched within
 * @param {search}    The value being searched for
 * @param {variables} The relevant variable names or the context object
 * @param {context}   The context object in which to search for the variable names
 *
 * @return The identified path as an array or null if nothing is found
 */
function getPath(obj, search, variables, context) {

    if(context === undefined) {
        context = window;        
    }

    if(variables === undefined) {
        variables = window;
    }
    if(!Array.isArray(variables)) {
        // if variables is an object, this object becomes the context
        context = variables;
        // copy the keys into the variables array
        variables = [];
        for(var key in context) {
            if(context.hasOwnProperty(key)) {
                try {
                    // attempt to read property
                    context[key];
                    // add key to variable names
                    variables.push(key);
                } catch(e) {
                    // some properties of the window object may not be readable
                }
            }
        }
    }

    function getVariableName(variable) {
        for(var i = 0; i < variables.length; i++) {
            var name = variables[i];
            if(context[name] === variable) {
                // provide variable name
                return name;
            }
        }
        return null;
    }

    function _getPath(variable, path) {
        if(typeof variable === 'object') {
            var name = getVariableName(variable);
            if(name) {
                var pathCopy = path.slice(0);
                pathCopy.push(name);
                for(var key in variable) {
                    // call _getPath recursively
                    var returnedPath = _getPath(variable[key], pathCopy);
                    if(returnedPath) {
                        return returnedPath;
                    }
                }
            }            
        } else if(variable === search) {
            return path;
        }
        // If no match is found, return null
        return null;
    }

    // Initiate the recursive search for the value
    return _getPath(obj, []);
}

By using the getPath function, you can accomplish the following:

var path = getPath(bigBox, "Batman");
console.log(path.join(" > ")); // prints "bigBox > mediumBoxB > smallBoxC > toyE"

If all variables are stored in one object, you can also utilize the getPath function with an additional context argument like so:

var path = getPath(context.bigBox, "Batman", context);



I have modified the object bigBox slightly, ensuring each variable appears exactly once in the object.

Check out the jsFiddle demo here

Answer №2

A tree can be traversed using enumeration to access each key and its respective name with the for x in y syntax. The key's name is contained in the value of X during each iteration. Create a search path by implementing your preferred recursive or iterative method for scanning the tree, then return the constructed path once you locate the desired value.

This approach represents a simple implementation strategy. While I cannot claim expertise in computer science, there may exist more efficient methods for conducting tree searches.

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

Discovering the magic of activating a JavaScript function on jQuery hover

I need to call a JavaScript function when hovering over an li element. var Divhtml='<div>hover</div>'; $('li a').hover(function(){ $(this).html(Divhtml); //I want to trigger hovercall(); wh ...

Retrieving text from Node.js with the help of regular expressions

I need to extract testcase ids from a list of testcases with titles. Each title includes an id and a description. I want to extract only the id. Here are some examples: TC-ABC-98.1.010_1-Verify the layout credit page TC-RegPMP-1.1.001_2-Verify the [MangerD ...

Utilizing a JavaScript class within the document ready function

Having trouble with a countdown script wrapped as an object in a separate file. Struggling to setup multiple counters or objects due to the timeout function in the countdown class not finding the object that was set up within the document ready event. Wh ...

React Material-UI Multiple Select with Checkboxes not displaying initial selections as checked

I am fairly new to working with React and MUI, so please bear with me. Currently, I am in the process of learning how to create Multiple Select Options with checkboxes by populating the Dropdown Options from an Array. Although I have set up the initial/de ...

Unable to change data in table TD using AJAX and PHP received JSON array

I am currently facing an issue with a PHP-AJAX script that is responsible for deleting financial rows from a table. The PHP script is functioning correctly and successfully deleting the rows. However, the problem arises within the success function of the A ...

Invoke a bounded function within an Angular directive using the ng-click event

I was wondering if it's possible to invoke a bound function within a directive by clicking on a specific part of a div. Currently, I have a div with an inner div that acts as a button for expanding the main div. The larger div has a directive associat ...

The MIME type for .rar and .tar files is not specified

Why is it that Javascript (Windows 8.1, Firefox) doesn't seem to recognize mime types for .tar files or .rar files, among others? Is there a way to fix this issue without resorting to unconventional methods? I really need to be able to get the mime ty ...

Unlocking numerical input solely by executing the specified command within the most up-to-date iteration of the Chrome Extension of Selenium IDE

After executing the command in Selenium IDE, I successfully extracted the sentence, "Your booking ID is 1234", and saved it in a variable named myText. <table> <tr> <th>Command</th> <th>Target</th> < ...

Creating a border around a div element using JavaScript

Is there a way to set a border for a div box using JavaScript similar to using border:2px solid #000; in CSS? Can this be done within the following for loop? elements = document.getElementsByClassName("box"); for (var i = 0; i < elements.length; i++) ...

Autocomplete causing issues with Mui visual display

Encountering an issue with my Mui components login page where autofill information collapses the placeholder. Essentially, when a saved username and password autofills the fields, the autocomplete details overlap with the placeholder text. See Bug Screens ...

Dealing with TSLint errors within the node_modules directory in Angular 2

After installing the angular2-material-datepicker via NPM, it is now in my project's node_modules folder. However, I am encountering tslint errors that should not be happening. ERROR in ./~/angular2-material-datepicker/index.ts [1, 15]: ' should ...

Is there a streamlined method for grouping labeled data points that share similarities?

I have a dataset structured like this: | Object | Related Objects | | ------| -------------- | | 1 | [1, 2, 6] | | 2 | [2, 1, 6] | | 3 | [3, 4] | | 4 | [4, 3] | | 5 | [5] | | 6 | [6, 1, 2] | ...

Setting the className in Next.js without using {styles.red} can be achieved by directly passing the

Description I'm trying to use just the pure class name without the {styles.class-name} convention in Next.js. After doing some research, I discovered that I need to configure the next.config.js file. Does anyone have good references for this? Current ...

Connect chosen options from Multicombobox in personalized UI5 control

I am looking to connect selectedItems, which are sourced from JsonModel in the controller, to a custom control. Custom control sap.ui.define([ 'sap/ui/core/Control', 'sap/m/MultiComboBox', ], function (Control, MultiComboBox) { ...

AngularJS: Updating data in controller but not reflecting in the HTML view

Within my AngularJS app, I've come across the following code: example.html <div> <p>{{name}}</p> </div> <div> <button ng-click="someFunction()"></button> </div> exa ...

What is the reason why an increment expression cannot be on the left side of an assignment?

I am trying to understand the significance of "++" in relation to arrays in the Java code snippet below: int [ ] arr = new int[ 4 ]; for(int i = 0; i < arr.length; i++){ arr[ i ] = i + 1; System.out.println(arr[ i ]++); } Can s ...

What are some ways to design unique custom data grid toolbar elements?

I am having trouble syncing my custom toolbar buttons with the imported material data grid toolbar components. I would like them to match in style, specifically applying the material styles to my custom components. However, I have not been able to find a w ...

The data provided is not in the correct format for a timestamp

Currently, I am utilizing the pg node module to establish a connection with PostgreSQL, and I have been attempting to run the following query: const res = await client.query(`SELECT number_transactions FROM transaction.city_unique_dates WHERE date_day_t ...

Creating an array of options for a jQuery plugin by parsing and populating

I am currently in the process of developing my very first jQuery plugin. The main function of this plugin involves taking JSON data and loading it into a table. Although most of the logic has been implemented successfully, I am facing challenges when it co ...

Immersive multimedia experience with HTML5 video interactivity

I am currently facing a challenge with inserting interactive buttons on a video in a responsive manner. Despite my efforts, I have not been successful yet. Screen 1 Screen 2 The screenshots provided depict the video at the end. The goal is to overlay t ...