Ways to extract data from a series of nested objects to form a new one through value comparisons

Initially, I have an object array

cart = [
  {
    "functional_id": "carton_de_10_coffrets_2_recharges_argile_offertes_coloris_rouge",
    "quantity": 6
  },
  {
    "functional_id": "identification_et_colliers_de_serrages_standard_par_50",
    "quantity": 2
  },
  {
    "functional_id": "carnet_de_conventions",
    "quantity": 3
  }
]

I need to compare this initial array with a nested array of objects. The nested array contains the objects from the first array and additional information needed to display the view of the app.

Here is the structure of the nested array:

market =[

{
  "name": "Articles funeraires",
  "functional_id": "funeral",
  "generic": "incineris",
  "products": [
    {
      "file": "data:image/;base64,",
      "name": "Boîte de sympathie",
      "id": 27,
      "path": "",
      "items": [
        {
          "name": "1 boîte",
          "price": 0,
          "functional_id": "boite_de_sympathie_1_boite"
        }
      ]
    },
    ...
]

Desired output:

[

{
      "name": "Articles funeraires",
      "products": [
                    "file": "data:image/;base64,",
                    "name": "Coffret empreinte rouge",
                    "path": "",
                    "items": [
                              {
                               "name": "Carton de 10 coffrets",
                               "price": 140,
                               "functional_id": "carton_de_10_coffrets_2_recharges_argile_offertes_coloris_rouge",
                               "quantity": 6
                              }
                             ]
                   ]
  } ,
...
]

In summary, I need to retrieve all the product info identified by their "functional_id" while keeping the original "quantity" in the initial array of objects.

My current approach only adds properties from the "item" level to each object in the "cart" array. However, I'm struggling to construct the desired structure.


cart.forEach(cartItem => {
            market.forEach(category => {
                category.products.forEach(product => {
                    product.items.forEach(item => {
                        if (cartItem.functional_id === item.functional_id) {
                            cartItem.subtitle = item.name;
                            cartItem.description = item.description;
                            cartItem.price = item.price;
                        }
                    });
                });
            });
        });

If you have any ideas on how to access and correct my initial approach to achieve the desired result, please let me know. Thank you in advance!

Answer №1

If you need quick access to specific functional_id within the cart, consider creating an object for that purpose.

To extract a subset, simplify nested properties and construct a new object containing only the desired elements.

var cart = [{ functional_id: "carton_de_10_coffrets_2_recharges_argile_offertes_coloris_rouge", quantity: 6 }, { functional_id: "identification_et_colliers_de_serrages_standard_par_50", quantity: 2 }, { functional_id: "carnet_de_conventions", quantity: 3 }],
    market = [{ name: "Articles funeraires", functional_id: ... 
// (Content truncated for brevity)
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

If you have prior knowledge of the nesting depth in your data structure and it remains constant, then you can achieve the desired outcome without using recursion (although recursion offers a more versatile solution):

  • Begin by creating a cart lookupItems Object (using reduce) for efficient lookups later
  • Proceed to map over markets
    • Then iterate through products within each market
      • Filter items based on presence in the cart lookupItems Object
    • Remove any products with empty item arrays
  • Discard markets with no products remaining

Note: An inconsistency was detected in the provided data that required modification of the cart to align with expected results; specifically, the item (""etiquettes_") was added to the beginning of ""functional_id"", whereas in the market data it starts with ""indentification_..."".

const cart = [
...,
  {
    "functional_id": "identification_et_colliers_de_serrages_standard_par_50",
    "quantity": 2
  },
...
];

const lookupItems = cart.reduce((aggObj, item) => {
  aggObj[item['functional_id']] = item;
  return aggObj;
}, {});

const output = markets.map(market => {  
  market.products = market.products.map(prod => {
    prod.items = 
        prod.items
          .filter(item => {
            if (lookupItems.hasOwnProperty(item['functional_id'])){
              item.quantity = lookupItems[item['functional_id']].quantity;
              return true;
            }
            return false;
          });
    return prod;
  }).filter(prod => prod.items.length >=1);  
  return {name: market.name, products: market.products};
})
.filter(market => market.products.length >=1);

console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script id="initData">
const cart = [
  {
    "functional_id": "carton_de_10_coffrets_2_recharges_argile_offertes_coloris_rouge",
    "quantity": 6
  },
  {
    "functional_id": "identification_et_colliers_de_serrages_standard_par_50",
    "quantity": 2
  },
  {
    "functional_id": "carnet_de_conventions",
    "quantity": 3
  }
];

const markets = [

{
  "name": "Articles funeraires",
  "functional_id": "funeral",
  "generic": "incineris",
  "products": [
    {
      "file": "data:image/;base64,",
      "name": "Boîte de sympathie",
      "id": 27,
      "path": "",
      "items": [
        {
          "name": "1 boîte",
          "price": 0,
          "functional_id": "boite_de_sympathie_1_boîte"
        }
      ]
    },
    ...
</script>

Desired Output:

[
  {
    "name": "Articles funeraires",
    "products": [
      {
        "file": "data:image/;base64,",
        "name": "Coffret empreinte rouge",
        "id": 8,
        "path": "",
        "items": [
          {
            "name": "Carton de 10 coffrets",
            "price": 140,
            "functional_id": "carton_de_10_coffrets_2_recharges_argile_offertes_coloris_rouge",
            "quantity": 6
          }
        ]
      }
    ]
  },
  ...
]

Answer №3

Utilizing flatMap for quantity addition and non-match filtering, with the use of destructuring to eliminate unwanted properties in the outputted object.

cartMap = {}
cart.forEach(({ functional_id: id, quantity }) => cartMap[id] = !quantity || {quantity})
// Condition to prevent overwriting quantity if it isn't defined

console.log(
market.flatMap(({ name, products }) => {
  products = products.flatMap(({ id, items, ...o }) => {
    o.items = items.flatMap(item => {
      const quantity = cartMap[item.functional_id]
      return quantity ? { ...item, ...quantity } : []
    })
    return o.items.length > 0 ? o : []
  })
  return products.length > 0 ? { name, products } : []
})
)
<head>
<script>
cart = [{
    "functional_id": "carton_de_10_coffrets_2_recharges_argile_offertes_coloris_rouge",
    "quantity": 6
  },
  {
    "functional_id": "identification_et_colliers_de_serrages_standard_par_50",
    // Potential typo?
    //"etiquettes_identification_et_colliers_de_serrages_standard_par_50",
    "quantity": 2
  },
  {
    "functional_id": "carnet_de_conventions",
    "quantity": 3
  }
]

market = [

  {
    "name": "Articles funeraires",
    "functional_id": "funeral",
    "generic": "incineris",
    "products": [/* Product details omitted for brevity */],
    "sorting": 2200
  },
  {
    "name": "Documents",
    "functional_id": "incineris_doc",
    "generic": "incineris",
    "products": [/* Product details omitted for brevity */],
    "sorting": 2400
  },
  {
    "name": "Matériel crémation",
    "functional_id": "furniture",
    "generic": "incineris",
    "products": [/* Product details omitted for brevity */],
    "sorting": 2300
  }
]
</script>
</head>

Answer №4

Just updated: Testing complete, should be functioning now. This code snippet will compare objects in a cart against those in a market array and return matches based on the 'functional_id' key.

const cart = [{ functional_id: "carton_de_10_coffrets_2_recharges_argile_offertes_coloris_rouge", quantity: 6 }, { functional_id: "identification_et_colliers_de_serrages_standard_par_50", quantity: 2 }, { functional_id: "carnet_de_conventions", quantity: 3 }]; const market = [{ name: "Articles funeraires", functional_id: "funeral", generic: "incineris", products: [{ file: "data:image/;base64,", name: "Boîte de sympathie", id: 27, path: "", items: [{ name: "1 boîte", price: 0, functional_id: "boite_de_sympathie_1_boite" }] }, ...al_id": "catalogue_urnes_decoratives" }] ]

Result:

[
  {
    "name": "Articles funeraires",
    "functional_id": "funeral",
    "generic": "incineris",
    "products": [
      {
        "file": "data:image/;base64,",
        "name": "Boîte de sympathie",
        ...
      }
    ],
    "sorting": 2200
  },
  {
    "name": "Matériel crémation",
    "functional_id": "furniture",
    "generic": "incineris",
    "products": [
      {
        "file": "data:image/;base64,",
        "name": "Sacs blancs",
        ...
      }
    ],
    "sorting": 2300
  },
  {
    "name": "Documents",
    "functional_id": "incineris_doc",
    "generic": "incineris",
    "products": [
      {
        "file": "data:image/;base64,",
        "name": "Carnet de conventions",
        ...
      }
    ],
    "sorting": 2400
  }
]

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

Find the total number of elements in the given ArrayList

I am working with an ArrayList that contains a collection of cars in inventory. The goal is to have the user input a start year and end year, and then determine the number of cars within that specified year range. Using a foreach loop, I need to display ...

Choose all div elements with a specified class from a variable

How can I retrieve all div elements with the "test" class from a variable and insert them into another div? var response = xmlhttp.responseText; var selectedDivs = $(response).find('.test'); $('.anotherdiv').prepend(selectedDivs); ...

Populating an integer array during its initialization

How can I declare an array named rows with a variable size X and initialize all values to 1? Currently, I am doing it like this: int[] rows = new int[X]; for (int i = 0; i < rows.Length; i++) { rows[i] = 1; } Is there a faster or shorter way to ach ...

Transient Flash of a jQuery Dropdown Menu

I'm currently developing a jQuery/CSS dropdown menu for a website, and everything is functioning well except for one issue. When navigating between sub-menu items, the text color of the selected main menu item briefly changes because of the CSS border ...

Struggling with sending data to a modal in AngularJS?

I am dealing with the following code snippet $scope.currentTask = undefined; $scope.openModal = function (task, size, parentSelector) { var parentElem = parentSelector ? angular.element($document[0].querySelector('.modal-d ...

Sorting an array of subdocuments within a populated query result in Node.js with Mongoose

I am looking to fetch recently submitted articles by members based on time. In the Member Schema, there is an array of _id values for submitted articles. Below are the details of the Member and Article Schemas: Member Schema const mongoose = require( ...

Determine how to use both the "if" and "else if" statements in

/html code/ There are 4 textboxes on this page for entering minimum and maximum budget and area values. The condition set is that the maximum value should be greater than the minimum value for both budget and area. This condition is checked when the form i ...

The lifecycle of XMLHTTPRequest objects in JavaScript - from creation to destruction

After years of working with traditional compiled object-oriented languages like C++ and .NET programming, I decided to dip my toes into JavaScript for a new project. As I was experimenting with AJAX, I stumbled upon a perplexing aspect related to how objec ...

Tips for dynamically loading images as needed

I'm working on a simple image zoom jQuery feature using elevateZoom. You can see a Demo example here. The implementation involves the following code: <img id="zoom_05" src='small_image1.png' data-zoom-image="large_image1.jpg"/> <sc ...

In what ways can we utilize a consistent state across various tabs or pages?

One feature of my application is a dynamic chart with various settings such as filters and time ranges. I want to save these settings in the app's state so they can be shared with other components on different pages. However, when switching tabs and r ...

What is the expected return type in TypeScript of a function that returns a void function?

I recently received feedback during a code review suggesting that I add return type values to my functions. However, I am unsure of what return type to assign to this particular function: function mysteryTypeFunction(): mysteryType { return function() ...

What is the best way to distinguish automatically generated links using JavaScript?

(Hello Dr. Nick) JavaScript is a new area for me and I am currently working on creating a website using asp.net EF JavaScript and other tools... I have created links based on the information stored in my database, and I want the name of the link to appea ...

In JavaScript, a button is programmed with a rare 1.04% probability of directing to Page A and a much higher 98.96% likelihood of redirecting to Page

My goal is to create a button that, when clicked, will have a 1.04% probability of navigating to Page A and a 98.96% chance of going to Page B. The challenge I'm facing is in randomizing these results using JavaScript. I am fairly new to this language ...

Fill up a dropdown menu in HTML when clicking on it

My webpage has multiple HTML select dropdowns that need to be populated onclick of the element. To achieve this, I use an AJAX call in the click event listener of the select elements. The decision to populate on click is driven by the importance of perfor ...

Is it possible to nest Route components in react-router version 4.x?

How can one properly implement nested routes in react-router version 4.x? Previous methods like the one below worked well, but upgrading to version 4.x now results in a warning... <Route path='/stuff' component={Stuff}> <Route path=&a ...

Storybook/vue causing issues with aliases not functioning as intended

I'm currently utilizing Storybook for Vue and I am endeavoring to integrate aliases into the webpack config within storybook/main.js: resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js', '@': path.resolve ...

Tips on how to ensure that an onClick JS function only runs when radio buttons are selected

I have implemented the formslider library for a form on my website. In the demo, the slide transitions to the next set of questions based on a click event triggered by radio buttons (answers). However, when I attempted to include checkboxes for users to s ...

React Native: Struggling with Button Styling

I am relatively new to React Native, although I have experience with React in my professional work. I'm finding that applying styles to components in React Native is a bit different than what I'm used to. Specifically, I am struggling to apply s ...

Maintaining the Readability of Promise Chains

Creating promise chains with arrays is a method I've become accustomed to. It's quite simple to follow along a chain of promises when each one fits neatly on its own line like so: myArray.map(x => convertX) .filter() .whatever() .etc() ...

Display an error popup if a server issue occurs

I'm considering implementing an Error modal to be displayed in case of a server error upon submitting a panel. I'm contemplating whether the appropriate approach would be within the catch statement? The basic code snippet I currently have is: u ...