Discovering the object and its parent within a series of nested arrays

Is there a way to locate an object and its parent object within a nested array of unknown size using either lodash or native JavaScript?

The structure of the array could resemble something like this:

name: 'Submodule122'

I have been using the following function to find the parent object, but it only works for the first level of the array:

_.find(this.modules , function(item) {
    return _.some(item.submodules, { name: 'Submodule122'});

And to locate the actual object, I've been using this code which also operates solely on the first level of the array:

_(this.modules)
    .thru(function (coll) {
        return _.union(coll, _.map(coll, 'submodules'));
    })
    .flatten()
    .find({ name: 'Submodule122'})

Answer №1

In order to find a specific object within an array, you can implement a combination of iterative and recursive techniques using the original object as a starting point.

function searchObject(name, items, parent) {
    var result;
    items.some(item =>
        item.name === name && (result = { item, parent }) || 
        (result = searchObject(name, item.submodules, item))
    );
    return result;
}

var modules = [{ name: 'Module1', submodules: [{ name: 'Submodule1', id: 1, submodules: [{ name: 'Submodule11', id: 1, submodules: [] }, { name: 'Submodule12', id: 2, submodules: [{ name: 'Submodule121', id: 1, submodules: [] }, { name: 'Submodule122', id: 2, submodules: [] }] }, { name: 'Submodule2', id: 2, submodules: [] }] }, { name: 'Module2', submodules: [{ name: 'Submodule1', id: 3, submodules: [] }, { name: 'Submodule2', id: 4, submodules: [] }] }] }];

console.log(searchObject('Submodule122', modules));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

let data = [{
    name: 'Module1',
    submodules: [{
        name: 'Submodule1',
        id: 1,
        submodules: [{
          name: 'Submodule11',
          id: 1,
          submodules: []
        }, {
          name: 'Submodule12',
          id: 2,
          submodules: [{
            name: 'Submodule121',
            id: 1,
            submodules: []
          }, {
            name: 'Submodule122',
            id: 2,
            submodules: []
          }]
        }]
      },
      {
        name: 'Submodule2',
        id: 2,
        submodules: []
      }
    ]
  },
  {
    name: 'Module2',
    submodules: [{
      name: 'Submodule1',
      id: 3,
      submodules: []
    }, {
      name: 'Submodule2',
      id: 4,
      submodules: []
    }]
  }
];

let findByName = (name, module, parent, item) => {
  parent.push(...module.filter(x => Array.isArray(x.submodules) && x.submodules.some(y => y.name == name)));
  item.push(...module.filter(y => y.name == name));

  module.forEach(x => {
    if (Array.isArray(x.submodules) && x.submodules.length > 0) {
      findByName(name, x.submodules, parent, item);
    }
  });

}

let parents = [], items = [];
findByName('Submodule12', data, parents, items);
console.log(parents);
console.log(items);

Answer №3

Although it may not be the exact solution you were looking for, I believe it's still valuable to share. Our team now relies on object-scan for handling all data processing tasks, and once you grasp its capabilities, it can be incredibly powerful. Here is how you could address your inquiries:

Please note that this function returns all parent elements, but you can easily extract the ones you need.

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

const search = (name, data) => objectScan(['**.name'], {
  rtn: 'parents',
  abort: true,
  filterFn: ({ value }) => value === name
})(data);

const modules = [{ name: 'Module1', submodules: [{ name: 'Submodule1', id: 1, submodules: [{ name: 'Submodule11', id: 1, submodules: [] }, { name: 'Submodule12', id: 2, submodules: [{ name: 'Submodule121', id: 1, submodules: [] }, { name: 'Submodule122', id: 2, submodules: [] }] }] }, { name: 'Submodule2', id: 2, submodules: [] }] }, { name: 'Module2', submodules: [{ name: 'Submodule1', id: 3, submodules: [] }, { name: 'Submodule2', id: 4, submodules: [] }] }];

console.log(search('Submodule122', modules));
/* =>
[ { name: 'Submodule122', id: 2, submodules: [] },
  [ { name: 'Submodule121', id: 1, submodules: [] },
    { name: 'Submodule122', id: 2, submodules: [] } ],
  { name: 'Submodule12',
    id: 2,
    submodules:
     [ { name: 'Submodule121', id: 1, submodules: [] },
       { name: 'Submodule122', id: 2, submodules: [] } ] },
  [ { name: 'Submodule11', id: 1, submodules: [] },
    { name: 'Submodule12',
      id: 2,
      submodules:
       [ { name: 'Submodule121', id: 1, submodules: [] },
         { name: 'Submodule122', id: 2, submodules: [] } ] } ],
  { name: 'Submodule1',
    id: 1,
    submodules:
     [ { name: 'Submodule11', id: 1, submodules: [] },
       { name: 'Submodule12',
         id: 2,
         submodules:
          [ { name: 'Submodule121', id: 1, submodules: [] },
            { name: 'Submodule122', id: 2, submodules: [] } ] } ] },
  [ { name: 'Submodule1',
      id: 1,
      submodules:
       [ { name:...

// Output truncated for simplicity

console.log(search('unknown', modules));
// => undefined
.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="533c31393630277e2030323d1362607d6b7d63">[email protected]</a>"></script>

Disclaimer: I am the developer behind 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

Angular 9: The instantiation of cyclic dependencies is not allowed

After transitioning from Angular 8 to Angular 9, I encountered an issue with a previously functioning HTTP communication service. The error message now reads: Error: Cannot instantiate cyclic dependency! HttpService at throwCyclicDependencyError (core ...

What is the best way to retrieve and display the heading of the current section that is being viewed using Bootstrap Vue's ScrollSpy feature?

I am currently using the Bootstrap Vue Scrollspy feature in my project with Nuxt js. The elements are correctly referenced and are successfully spying on the content. What I would like to achieve is having the ability to update a specific div with the curr ...

The value is undefined until a new Resource object is pushed with the item

I've encountered an issue while testing a factory and I can't seem to find anyone else with the same problem. Can someone help me figure out what's causing this strange error? TypeError: 'undefined' is not a function (evaluating & ...

Preloading error alert message displayed during AJAX request

When I send an ajax request with a dropdown change, the loader div is shown using "before send". However, the issue is that the loader only displays for the first time, even though the ajax functionality works all the time. If you want to check this issue ...

Can you share tips for passing a variable from a post request to a function that accepts parameters as a string or an array of strings in Node.js?

I am struggling to insert the variable named query into the end of the prompt. I attempted to use template literals but it was unsuccessful. (async () => { const gbtResponse = await openai.createCompletion({ model: "text-davinci-002", prompt ...

The datatype 'string' cannot be assigned to the datatype '(token: string) => void'

Within my Angular2 application, I have a class that includes several properties which will be assigned values within components. @Injectable() export class Globals { private token: string; private authorization: string; private roleUser: boole ...

What is causing the error message 'undefined is not a function' to appear in my code?

Struggling to send a file in response to a GET request with express.js. I created a basic FileManager class to manage file requests, yet encountering an error of 'undefined is not a function' when calling new FileManager() Here's my approac ...

I am encountering problems with converting Array to JSON format in PHP for utilization in Javascript

I always face challenges when it comes to converting Array into JSON format. Currently, I am utilizing a selectbox plugin developed by TexoTela. For this plugin to work, it requires a specific JSON structure as shown below: { "ajax1": "AJAX option 1 ...

Create a custom loading spinner for a jQuery AJAX request

How can I add a loading indicator to my Bootstrap modal that is launched from a link? Currently, there is a 3-second delay while the AJAX query fetches data from the database. Does Twitter Bootstrap have built-in functionality for this? UPDATE: Modified J ...

Phonegap - Retaining text data in a checklist app beyond app shutdown

This is my first time developing an app with Phonegap. I am looking to create a checklist feature where users can input items into an input field. However, I am struggling with figuring out how to save these items so that they remain in the checklist even ...

Trouble experienced with the window.open() function on Safari

When using Safari, it can sometimes block the opening of a new tab through the window.open() function during an ajax call. To bypass this blocking, we must first call window.open() to open a new tab before making the ajax call. Refer to this Stack Overflow ...

Linking several asynchronous functions together in JavaScript

class Calculation { constructor(num) { this.num = num; } performAddition() { // code } performSubtraction() { // code } performMultiplication() { // code } performDivision() { // code } } const getResult = async ...

Utilizing the URL path name for data retrieval in Next.js 14 - A step-by-step guide

I'm currently developing a blog using AWS Amplify Gen 2 and GraphQL for a Next.js 14 project with TypeScript. As part of my application, I need to fetch specific data based on the URL path name. Here's how I've approached it: My approach in ...

Linking chained functions for reuse of code in react-redux through mapStateToProps and mapDispatchToProps

Imagine I have two connected Redux components. The first component is a simple todo loading and display container, with functions passed to connect(): mapStateToProps reads todos from the Redux state, and mapDispatchToProps requests the latest list of todo ...

Implementing a one-time watcher with user input in Vue.js

I am facing an issue with using the input tag in a Vue template. I need to change the type from 'password' to 'text'. <input type="text" v-model="form.password" /> To achieve this, I have created a watch code to convert text s ...

What is the best way to locate the closest element using JavaScript?

Is there a way to locate the closest object to the mouse pointer on a webpage? I have a hypothesis that involves utilizing the array function, however, I am uncertain if that is the correct approach. Furthermore, I lack knowledge of which specific proper ...

Is it possible for me to pass a reference to a specific object's instance function?

Can JavaScript allow you to pass a function reference to a specific object's function, similar to what can be done in Java? Let's take a look at this code snippet: _.every(aS, function (value) { return exp.test(value); }); What if we want ...

Incorporate a JavaScript form into a controller in MVC4

I'm facing an issue where I need to trigger a JavaScript function from within a controller method in my project. Here is the code snippet that I am using: Public Function redirectTo() As JavaScriptResult Return JavaScript("ToSignUp()") E ...

Handling type errors with React Typescript MuiAccordion OnChange event handler

I'm a beginner in typescript and seeking advice on defining the type for an event handler. I have a component that utilizes material ui Accordion and triggers the handler from a container. Therefore, I need to specify the type of handleChange in my co ...

What steps do I need to take to set up CORS properly in order to prevent errors with

I encountered the following error message: "Access to XMLHttpRequest at 'api-domain' from origin 'website-domain' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HT ...