Discover the paths to locate all keys within an object that correspond to a specified string

I need help creating a function in plain JavaScript that can find all paths to keys with a specific name in an object. The object may have repeated key names at different depths.

Here is an example:

const obj = {
    stuff: {
        A: 'text'
    },
    deeperStuff: {
        nested: {
            A: ['data']
        }
    }
};

const func = (object, key) => {
    ...
};

console.log(func(obj, 'A'));
// [['stuff', 'A'], ['deeperStuff', 'nested', 'A']]

If anyone has a solution for this problem, I would greatly appreciate it!

Thank you,

P

Answer №1

How about implementing a function that takes an object and iterates through its keys to find a specific match? If a match is found, it is added to a hash table (with a different output type). If the value corresponding to the key is another object, recursion is used to search within that nested object.

const myObj = {
    stuff: {
        A: 'text'
    },
    deeperStuff: {
        nested: {
            A: ['data']
        }
    }
};

function findKeys(obj, desiredKey, path = [], results = {}) {
  const keys = Object.keys(obj)
  keys.forEach(function(key) {
    const currentPath = path.concat([key])
    if (key === desiredKey) {
      results[currentPath.join('/')] = obj[key]
    } 
    if (typeof obj[key] === "object") {
      findKeys(obj[key], desiredKey, currentPath, results)
    }
  })
  return results
}

// modified function to achieve the same result with a different return type
function findKeyArray(obj, desiredKey, path = [], results = []) {
  const keys = Object.keys(obj)
  keys.forEach(function(key) {
    const currentPath = path.concat([key])
    if (key === desiredKey) {
      results.push(currentPath); // changed this line
    } 
    if (typeof obj[key] === "object") {
      findKeyArray(obj[key], desiredKey, currentPath, results); // and this line ;)
    }
  })
  return results
}

console.log(findKeys(myObj, "A"))
console.log(findKeyArray(myObj, "A"))

expected outputs:

{
  deeperStuff/nested/A: ["data"],
  stuff/A: "text"
}

[["stuff", "A"], ["deeperStuff", "nested", "A"]]

Answer №2

One way to find a specific key within a nested object is by using a combination of iterative and recursive methods without the need to store the visited path.

function searchForKey(object, key) {
    return Object
        .entries(object)
        .reduce((result, [k, value]) => {
            if (k === key) {
                return result.concat(k);
            }
            if (value && typeof value === 'object') {
                searchForKey(value, key).forEach(temp => result.push([k, ...temp]));
            }
            return result;
        }, []);
}

const myObject = { stuff: { A: 'text' }, deepStuff: { nested: { A: ['data'] } } };

console.log(searchForKey(myObject, 'A'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №3

If you're looking for a solution that allows for complex patterns in the search path, consider using object-scan. Although it is concise and powerful, keep in mind that adding this dependency comes with a trade-off.

// const objectScan = require('object-scan');

const myObj = { stuff: { A: 'text' }, deeperStuff: { nested: { A: ['data'] } } };

console.log(objectScan(['**.A'])(myObj));
// => [ [ 'deeperStuff', 'nested', 'A' ], [ 'stuff', 'A' ] ]

console.log(objectScan(['**.stuff.A'])(myObj));
// => [ [ 'stuff', 'A' ] ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5a3538303f392e7729393b341a6b697462746a">[email protected]</a>"></script>

Disclaimer: This information was provided by the author of object-scan

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

How to Save Checkbox Selections in the Order They Were Clicked Using PHP

I have a form with 4 checkboxes, and I need to save the selected checkboxes in the database in the order they are clicked. For example, if the checkboxes are clicked in the sequence 1, 3, 4, 2, then they should be saved in the database in that exact order. ...

Unusual shift in the modal's behavior occurs when the parent component's style.transform is applied

I have encountered an unusual issue with a modal's appearance and functionality. The modal is designed to enlarge images sent in a chat, with the chat upload preview div serving as the parent element and the modal as the child element. This strange be ...

What is the best way to create a reset button for a timing device?

Is there a way to reset the timer when a button is clicked? Having a reset button would allow users to revisit the timer multiple times without it displaying the combined time from previous uses. Check out this code snippet for one of the timers along wit ...

Vue.js does not support the usage of external JSON files directly within HTML documents

I'm encountering issues fetching data from an external JSON file for a specific variable. I suspect that the problem lies in using Vue.js within the HTML, as it seems to be having trouble interpreting my code correctly.:joy: jsfiddle Additionally, I ...

Error: The requested resource does not have the 'Access-Control-Allow-Origin' header. The request is successful, but an error is being triggered

As I am trying to make an Ajax cross domain request, I have come across a strange issue. In the console of Chrome dev tools, I see the following error: "No 'Access-Control-Allow-Origin' header is present on the requested resource" Despite this ...

Generating elements added at various depths within an HTML document with the help of JavaScript

create_new.append("div") .append("form").merge(update_5) .attr("action", d => d.market) .attr("target","_blank") .style("width","100%") .style("height","282") .append("input").merge(update_5) .attr("type","submit") ...

Click handler that transmits data to a server using ajax

I have been tasked with creating a website using HTML, CSS, and JavaScript that includes three buttons. When clicked, these buttons will send codes such as "10," "01," and "11" to a C++ program. The C++ program will then respond and perform a function base ...

Obtain the complete path in Vue router by utilizing nested routes

After creating nested routes for Vue Router, I encountered a problem while using the routes to generate a navigation menu. Currently, I am using route.path in 'router-link :to=' which only gives me a part of the path. I want to include the absolu ...

Activating the Mobile Menu Function when the Window is Resized

I've developed a JavaScript function that triggers on window resize. When switching between landscape and portrait orientation on mobile devices or tablets, the window dimensions change. This functionality is also useful for browser testing on desktop ...

Comparing JSON files in JavaScript to identify and extract only the new objects

I need a way to identify and output the newly added objects from two JSON files based on their "Id" values. It's important for me to disregard changes in object positions within the files and also ignore specific key-value changes, like Greg's ag ...

Video texture incorporated into Three.js

I'm currently experimenting with using a specific section of a video as a texture on a Three.js mesh. The video in question can be found at this link: . It features a fisheye lens, and I am only interested in incorporating the central circular portio ...

Error encountered in MVC 5: When using jQuery to assign a value to an object, the

Currently tackling a web development project as a newbie in the field and running into an issue with this snippet of code (which sets the end date to tomorrow if left blank): var date = new Date($('#txtStartDate').val()); var tomorrow = date.ge ...

Eliminate the ArrayOfObjects by filtering out the items with a specific ID

Here is an array of objects I've named mycart[]: [{"id":"6","quantity":"20","price":1500,"title":"casual blue strip"}, {"id":"10","quantity":"2","price":1500,"title":"casual blue round neck"},{"id":"5","quantity":20,"price":150,"title":"casual ...

Error arises when uploading csv files to Node.js with Multer due to an unexpected field presence

I'm currently working on implementing a file upload feature with the use of Node.js, Vue, and Multer. Below is the Vue.js front-end code: export default { data(){ return{ selected: "How do you want to input the data?", options: [ ...

Issues with AngularJS dirty validation for radio buttons not being resolved

I have encountered an issue with my form fields. The validation for the email field is working correctly, but the radio button field is not displaying any errors when it should. I am using angular-1.0.8.min.js and I cannot figure out why this is happenin ...

unable to locate the font file I recently downloaded in the Windows terminal

Interested in customizing your Windows terminal? I recently decided to change my font style and downloaded the desired one. However, despite seeing the font in control panel and trying the "downloading for every user" option, my terminal still can't l ...

What is the best method for effectively organizing and storing DOM elements alongside their related objects?

In order to efficiently handle key input events for multiple textareas on the page, I have decided to create a TextareaState object to cache information related to each textarea. This includes data such as whether changes have been made and the previous co ...

What could be causing the issue with ng-include not functioning properly?

Issue with ng-include Organized Directory Structure : ssh_project --public ----templates ------header.html ------footer.html ----views ------index.html Here is the content of my index.html file <body> <h1>Hello</h1> <div ng ...

What is the reason that the 'mouseenter' event only applies to the initial element in each round of iteration within a spacebar loop?

My goal is to create an off-canvas menu within a template component. I found inspiration from this helpful article. The setup I have is quite common: A container tab where I loop through an items collection An item component that contains the off-canvas ...

Exploring the use of the caret symbol (^) for exponentiation

I am embarking on a project to develop an uncomplicated graphing calculator that enables users to input a function of f (such as f(x) = x^2+2x+6). Essentially, the JavaScript code should replace the x in the function with a specific number and then compute ...