Filter an array of objects recursively based on various properties

I need help filtering an object with nested arrays based on specific criteria. Specifically, I want to filter the main array by matching either RazaoSocial:"AAS" or Produtos:[{Descricao:"AAS"}]

This is my code:

var input = [
  {
    RazaoSocial: 'AAS',
    Produtos: [
    { DescricaoProduto: 'XXX', id:12, other:"other text" },
      { DescricaoProduto: 'YYY', id:12, other:"other text" }
    ]
  },
  {
    RazaoSocial: 'I found you',
    Produtos: [
      { DescricaoProduto: 'AAS', id:12, other:"other text" },
      { DescricaoProduto: 'Miss8', id:12, other:"other text" },
      { DescricaoProduto: 'Miss8', id:12, other:"other text" },
      { DescricaoProduto: 'Miss8', id:99, other:"other text" }      
    ]
  },
  {
    RazaoSocial: 'bla',
    Produtos: [
        { DescricaoProduto: 'AB', id:12, other:"other text" },
        { DescricaoProduto: 'CD', id:12, other:"other text" },
    ]
  },  
];

var res = input.filter(function f(o) {
    if (o.RazaoSocial.includes("AAS")) return true
    if (o.Produtos.DescricaoProduto) {
        console.log(o.Produtos);
        return (o.Produtos = o.Produtos.filter(f)).length
    }
})
 console.log(JSON.stringify(res, null, 2));

//result

[
  {
    "RazaoSocial": "AAS",
    "Produtos": [
      {
        "DescricaoProduto": "XXX",
        "id": 12,
        "other": "other text"
      },
      {
        "DescricaoProduto": "YYYAAS",
        "id": 12,
        "other": "other text"
      }
    ]
  }
]

I'm wondering why the object with RazaoSocial "I found you" is not returned in the result even though it meets the criteria.

[
        {
            RazaoSocial: 'AAS',
            Produtos: [
                { DescricaoProduto: 'XXX', id: 12, other: "other text" },
                { DescricaoProduto: 'YYY', id: 12, other: "other text" }
            ]
        },
        {
            RazaoSocial: 'I found you',
            Produtos: [
                { DescricaoProduto: 'AAS', id: 12, other: "other text" },
                { DescricaoProduto: 'Miss8', id: 12, other: "other text" },
                { DescricaoProduto: 'Miss8', id: 12, other: "other text" },
                { DescricaoProduto: 'Miss8', id: 99, other: "other text" }
            ]
        }
    ]

I have tried various examples without success. Can someone please point out where I might be going wrong?

Thank you for your assistance.

Answer №1

The primary issue in the initial attempt was the usage of if (o.Products.Description)

o.Products is an array, so accessing o.Products.Description directly requires specifying an index first.

Since o.Products is an array, it needs to be filtered similar to the original input.

I've included both a recursive and non-recursive method for comparison.

The recursive solution is versatile and can locate any desired value.

var input = [
  {
    Name: 'AAS',
    Products: [
      { Description: 'XXX', id:12, other:"other text" },
      { Description: 'YYY', id:12, other:"other text" }
    ]
  },
  {
    Name: 'I found you',
    Products: [
      { Description: 'AAS', id:12, other:"other text" },
      { Description: 'Miss8', id:12, other:"other text" },
      { Description: 'Miss8', id:12, other:"other text" },
      { Description: 'Miss8', id:99, other:"other text" }      
    ]
  },
  {
    Name: 'bla',
    Products: [
        { Description: 'AB', id:12, other:"other text" },
        { Description: 'CD', id:12, other:"other text" },
    ]
  },  
];

var useRecursive = true, 
    res;
if (useRecursive) {
  var findValue = function (str) {
      return function(o) {
          return Object.values(o).filter(function (value) {
              if (Array.isArray(value)) {
                  return value.filter(findValue(str)).length > 0
              } else {
                  return value.toString().includes(str)
              }
          }).length > 0;
      };
  };
  res = input.filter(findValue("AAS"))

} else {
  res = input.filter(function f(o) {
    if (o.Name.includes("AAS")) return true
    if (o.Products.length) {
        return o.Products.filter(function(o1) {
          return o1.Description.includes("AAS");
        }).length;
    }
  })
}
console.log(JSON.stringify(res, null, 2));

Answer №2

let result = data.map(function filterFunction(obj) {
    let returnValue = false;
    if (obj.Name.includes("XYZ")) returnValue  = true
    if (obj.Items.Description) {
        console.log(obj.Items);
        returnValue  = (obj.Items = obj.Items.filter(filterFunction)).length
    }
    return returnValue; 
})

I have not tested this code yet, so please use it cautiously

Answer №3

Instead of using recursion, you can achieve the desired result by implementing a simple filter like the one below:

var filteredObjects = input.filter(function (object) {
 return object.RazaoSocial.includes("AAS") ||
   object.Products && object.Products.find(function (product) {
     return product.ProductDescription === 'AAS';
 }));
console.log(JSON.stringify(filteredObjects, null, 2));

This code snippet will give you an array containing objects with RazaoSocial matching 'AAS' or Products with ProductDescription equal to 'AAS'.

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

incorporating theme.spacing in the declaration of the theme

The theme setup that I am working with is as follows: export const themeDefault = createTheme({ themeName: 'Default (Mortgage Hub)', spacing: 4, ...typography, palette, components: { MuiButton: { styleOverrides: { root ...

Managing file sizes on the client side prior to transferring them to the server side

I am looking to implement client-side validation for file size. The current code only handles success, but I also want to address file size limitations. Right now, if a file exceeds 2MB, it results in a 500 (Internal Server Error) behind the scenes. Is th ...

How can I retrieve the PHP response once a successful upload has occurred using DropzoneJS?

I am currently in the process of integrating Dropzone into my website. My goal is to capture the "success" event and extract specific information from the server response to add to a form on the same page as the DropZone once the upload is finished. The k ...

Error occurred when attempting to fetch data from a nested JSON object in React/Next.JS

Having trouble retrieving data from my API and encountering this error message. I suspect it may be related to the JSON structure. Interestingly, when using a different URL with nested arrays, it works fine. However, my current data is not cooperating. Any ...

What is the best way to adjust the placement of a component to remain in sync with the v-model it is connected to?

I am encountering an issue with 2 sliders in my project. I have set it up so that when the lower slider's value is greater than 0, the top slider should automatically be set to 5. I am using a watcher function for this purpose. However, if I manually ...

Can JQuery be used to identify the CSS styles applied to selected elements?

Highlight the text by selecting it and clicking a button. If the text is already highlighted, clicking the button should make the selected text return to normal. Can this be achieved using jQuery and a single button? Is it possible to identify the CSS st ...

Ways to convert a JavaScript object's properties into JSON format

I am currently manually going through the properties of my javascript class to create JSON, as shown below. It feels cumbersome and I am looking to automate this process so that I don't have to make changes to the 'toJson' function every tim ...

What discrepancies exist between running npm install on Windows versus Linux operating systems?

Just have a quick question to ask. I've been searching online with no luck. If I were to run npm install on a Windows machine to set up my dependencies, would it be viable to transfer the node_modules directory to a Linux machine and execute my nodej ...

Arranging a nested JSON array directly

Below is the structure of my JSON data : Root |- cells [] |-Individual cells with the following |- Facts (Object) |- Measures (Object) |- Key value pairs |- other valu ...

Troubleshooting Problem with Creating a Button using HTML Checkbox "onclick" Event

My main goal with the checkbox click event is to achieve the following objectives: 1] Create a button with the id = 'id-of-checkbox'+'some-character-here' in a specific div. 2] Clicking on that button will remove both the button and ...

Tips for linking weight scale device to a website

I recently developed a web application that calculates the weight of products. The application was created using PHP, JavaScript, and AJAX, running on a XAMPP server. Now my client is requesting for me to integrate a weight scale machine into the applica ...

Analyzing JSON parsing efficiency

I am currently working on a client application using jquery and html5 For my project, I have a data file that is 70 MB in size The file named data.json contains the following: var myData = [ { "id":"000000001", "title":"title1", "c ...

Having trouble with updating label text in MUIDataTable in ReactJS?

Looking to implement multi-language support in MUI Datatables. I have been able to modify the translations, but when attempting to change languages by providing a different object with new translations (verified using console log), the label texts do not u ...

Unable to access filteredItems from custom popup in uib-typeahead retrieval process

Issue with Retrieving Filtered Items from ng-repeat in Controller using $scope Despite trying to fetch filtered items from ng-repeat, the value of $scope.filteredItems appears as undefined when I log it to the console. I attempted to implement the solutio ...

Triggering a form submission in JavaScript when a selection is changed

Welcome to my WordPress site! If you would like to check it out, visit this link. Currently, I have a form located next to the text "Filter By Location:". My goal is to have the form submitted automatically when one of the options is selected (onChange). ...

Utilize Fb.api to automatically post on user's wall upon logging in

I want to utilize fb.api to make a single post on the logged-in user's wall. Here is the code snippet: var params = {}; params['message'] = 'gegeegeggegall! Check out www.facebook.com/trashcandyrock for more info.'; params['n ...

Values in Vuex do not get updated by getters

I'm having trouble understanding the functionality of getters in Vuex. The issue arises when I log out the token and find that the state and localStorage are empty, but the getters still contain the old token value. In the created lifecycle hook, I ha ...

I encounter difficulty utilizing assets within my React application

Currently, I am in the process of developing a React application for practice purposes. However, I have encountered an issue with using images and audio files stored in the assets folder. Despite my attempts to import them into the project, I have been uns ...

Using NodeJS, pull JSON data from a JavaScript file and render it in a route file

I am currently utilizing Nodejs Express to work with a script that generates an array of objects from the Google API. My objective is to integrate this JSON data into my templates. How can I invoke the function within my script file from my route file? Be ...

Discovering the number of intervals running at any given time within the console - JavaScript

I'm having trouble determining if a setInterval() is active or has been cleared. I set up an interval and store it in a variable: interval = setInterval('rotate()',3000); When a specific element is clicked, I stop the interval, wait 10 sec ...