Search code examples
javascriptarraysforeacharrayobject

How to get information from an array of nested objects to create another one by comparing values?


I have an initial 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
  }
]

which I need to compare with an array of nested objects, in which are the objects of the first array, to complete its information to display the view of the app

the structure of the array of nested objects is as follows

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"
        }
      ]
    },
    {
      "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"
        }
      ]
    },
    {
      "file": "data:image/;base64,",
      "name": "AfuBOX",
      "id": 10,
      "path": "",
      "items": [
        {
          "name" : "PACK N°1 comprenant :",
          "price": 30,
          "functional_id": "afubox_6_petits_modeles_4_moyens_modeles",
          "quantity": 4
        },
        {
          "name" : "PACK N°2 comprenant :",
          "price": 70,
          "functional_id": "afubox_6_petits_modeles_4_moyens_modeles",
          "quantity": 6
        }

      ]
    },
    {
      "file": "data:image/;base64,",
      "name": "Catalogue d'urnes décoratives",
      "id": 20,
      "path": "",
      "items": [
        {
          "price": 0,
          "functional_id": "catalogue_urnes_decoratives"
        }
      ]
    }
  ],
  "sorting": 2200
},
  {
  "name": "Documents",
  "functional_id": "incineris_doc",
  "generic": "incineris",
  "products": [
    {
      "file": "data:image/;base64,",
      "name": "Carnet de conventions",
      "id": 17,
      "path": "",
      "items": [
        {
          "price": 0,
          "functional_id": "carnet_de_conventions",
          "quantity": 3
        }
      ]
    },
    {
      "file": "data:image/;base64,",
      "name": "Affiches procédure",
      "description": "De prise en charge et de crémation des animaux",
      "id": 18,
      "path": "",
      "items": [
        {
          "price": 0,
          "functional_id": "affiches_procedure_de_prise_en_charge_et_de_cremation_des_animaux"
        }
      ]
    },
    {
      "file": "data:image/;base64,",
      "name": "Dépliants services de crémation",
      "description": "Pour animaux de compagnie",
      "id": 19,
      "path": "",
      "items": [
        {
          "price": 0,
          "functional_id": "depliants_services_incinération",
          "quantity": 4
        }
      ]
    },
    {
      "file": "data:image/;base64,",
      "name": "Catalogue d'urnes décoratives",
      "id": 20,
      "path": "",
      "items": [
        {
          "price": 0,
          "functional_id": "catalogue_urnes_decoratives"
        }
      ]
    }
  ],
  "sorting": 2400
},
{
  "name": "Matériel crémation",
  "functional_id": "furniture",
  "generic": "incineris",
  "products": [
    {
      "file": "data:image/;base64,",
      "name": "Sacs blancs",
      "description": "Pour les crémations Plurielles",
      "id": 11,
      "path": "",
      "items": [
        {
          "name": "Petit modèle",
          "description": "Par 25",
          "price": 0,
          "functional_id": "sacs_blancs_pour_les_cremations_plurielles_petit_modele_par_25"
        },
        {
          "name": "Moyen modèle",
          "description": "Par 20",
          "price": 0,
          "functional_id": "sacs_blancs_pour_les_cremations_plurielles_moyen_modele_par_20"
        },
        {
          "name": "Grand modèle",
          "description": "Par 10",
          "price": 0,
          "functional_id": "sacs_blancs_pour_les_cremations_plurielles_grand_modele_par_10"
        }
      ]
    },
    {
      "file": "data:image/;base64,",
      "name": "Sacs bordeaux",
      "description": "Pour les crémations Référence",
      "id": 12,
      "path": "",
      "items": [
        {
          "name": "Petit modèle",
          "description": "Par 25",
          "price": 0,
          "functional_id": "sacs_bordeaux_pour_les_cremations_reference_petit_modele_par_10"
        },
        {
          "name": "Grand modèle",
          "description": "Par 10",
          "price": 0,
          "functional_id": "sacs_bordeaux_pour_les_cremations_reference_grand_modele_par_10"
        }
      ]
    },
    {
      "file": "data:image/;base64,",
      "name": "Sacs verts",
      "description": "Pour les crémations Privées",
      "id": 13,
      "path": "",
      "items": [
        {
          "name": "Petit modèle",
          "description": "A l'unité",
          "price": 0,
          "functional_id": "sacs_verts_pour_les_cremations_privees_petit_modele_unite"
        },
        {
          "name": "Moyen modèle",
          "description": "A l'unité",
          "price": 0,
          "functional_id": "sacs_verts_pour_les_cremations_privees_moyen_modele_unite"
        },
        {
          "name": "Grand modèle",
          "description": "A l'unité",
          "price": 0,
          "functional_id": "sacs_verts_pour_les_cremations_privees_grand_modele_unite"
        }
      ]
    },
    {
      "file": "data:image/;base64,",
      "name": "Sacs bleus",
      "description": "Pour pièces anatomiques",
      "id": 14,
      "path": "",
      "items": [
        {
          "name": "Standard",
          "description": "Par 25",
          "price": 0,
          "functional_id": "sacs_bleus_pour_pieces_anatomiques_standard_par_25"
        }
      ]
    },
    {
      "file": "data:image/;base64,",
      "name": "Etiquettes d'identification",
      "id": 15,
      "path": "",
      "items": [
        {
          "name": "Standard",
          "description": "Par 50",
          "price": 0,
          "functional_id": "identification_et_colliers_de_serrages_standard_par_50"
        }
      ]
    },
    {
      "file": "data:image/;base64,",
      "name": "Colliers de serrages",
      "id": 16,
      "path": "",
      "items": [
        {
          "name": "Standard",
          "description": "Par 50",
          "price": 0,
          "functional_id": "distributeurs_pour_sacs_housse_par_5"
        }
      ]
    }
  ],
  "sorting": 2300
}
]

my desired output would be the following

[

{
      "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
                              }
                             ]
                   ]
  } ,
{
      "name": "Matériel crémation",
      "products": [
                    "file": "data:image/;base64,",
                    "name": "Etiquettes d'identification",
                    "path": "",
                    "items": [
                              {
                               "name": "Standard",
                               "description": "Par 50",
                               "price": 0,
                               "functional_id": "identification_et_colliers_de_serrages_standard_par_50",
                               "quantity": 2
                              }
                             ]
                   ]
  } ,


    {
      "name": "Documents",
      "products": [
                    "file": "data:image/;base64,",
                    "name": "Carnet de conventions",
                    "path": "",
                    "items": [
                              {
                               "price": 0,
                               "functional_id": "carnet_de_conventions",
                               "quantity": 3
                              }
                             ]
                   ]
  } 
]

in short, what I need to do is to recover all the info of the product identified by its "functional_id" keeping the original "quantity" in the first array of objects

What I'm trying doesn't work, because there comes a point where it doesn't let me access the information at the beginning of the nested object array


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;
                        }
                    });
                });
            });
        });

With this I only manage to put in each object of the "cart" properties at the "item" level in the forEach, but I don't see how to mount the desired structure... Someone to give me an idea of how to access that data and correct my initial approach Thank you in advance


Solution

  • You could take an object for having a faster access to the wanted functional_id of the cart.

    For getting a subset, you could reduce nested properties and build new object with the wanted parts.

    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: "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" }] }, { 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" }] }, { file: "data:image/;base64,", name: "AfuBOX", id: 10, path: "", items: [{ name: "PACK N°1 comprenant :", price: 30, functional_id: "afubox_6_petits_modeles_4_moyens_modeles", quantity: 4 }, { name: "PACK N°2 comprenant :", price: 70, functional_id: "afubox_6_petits_modeles_4_moyens_modeles", quantity: 6 }] }, { file: "data:image/;base64,", name: "Catalogue d'urnes décoratives", id: 20, path: "", items: [{ price: 0, functional_id: "catalogue_urnes_decoratives" }] }], sorting: 2200 }, { name: "Documents", functional_id: "incineris_doc", generic: "incineris", products: [{ file: "data:image/;base64,", name: "Carnet de conventions", id: 17, path: "", items: [{ price: 0, functional_id: "carnet_de_conventions", quantity: 3 }] }, { file: "data:image/;base64,", name: "Affiches procédure", description: "De prise en charge et de crémation des animaux", id: 18, path: "", items: [{ price: 0, functional_id: "affiches_procedure_de_prise_en_charge_et_de_cremation_des_animaux" }] }, { file: "data:image/;base64,", name: "Dépliants services de crémation", description: "Pour animaux de compagnie", id: 19, path: "", items: [{ price: 0, functional_id: "depliants_services_incinération", quantity: 4 }] }, { file: "data:image/;base64,", name: "Catalogue d'urnes décoratives", id: 20, path: "", items: [{ price: 0, functional_id: "catalogue_urnes_decoratives" }] }], sorting: 2400 }, { name: "Matériel crémation", functional_id: "furniture", generic: "incineris", products: [{ file: "data:image/;base64,", name: "Sacs blancs", description: "Pour les crémations Plurielles", id: 11, path: "", items: [{ name: "Petit modèle", description: "Par 25", price: 0, functional_id: "sacs_blancs_pour_les_cremations_plurielles_petit_modele_par_25" }, { name: "Moyen modèle", description: "Par 20", price: 0, functional_id: "sacs_blancs_pour_les_cremations_plurielles_moyen_modele_par_20" }, { name: "Grand modèle", description: "Par 10", price: 0, functional_id: "sacs_blancs_pour_les_cremations_plurielles_grand_modele_par_10" }] }, { file: "data:image/;base64,", name: "Sacs bordeaux", description: "Pour les crémations Référence", id: 12, path: "", items: [{ name: "Petit modèle", description: "Par 25", price: 0, functional_id: "sacs_bordeaux_pour_les_cremations_reference_petit_modele_par_10" }, { name: "Grand modèle", description: "Par 10", price: 0, functional_id: "sacs_bordeaux_pour_les_cremations_reference_grand_modele_par_10" }] }, { file: "data:image/;base64,", name: "Sacs verts", description: "Pour les crémations Privées", id: 13, path: "", items: [{ name: "Petit modèle", description: "A l'unité", price: 0, functional_id: "sacs_verts_pour_les_cremations_privees_petit_modele_unite" }, { name: "Moyen modèle", description: "A l'unité", price: 0, functional_id: "sacs_verts_pour_les_cremations_privees_moyen_modele_unite" }, { name: "Grand modèle", description: "A l'unité", price: 0, functional_id: "sacs_verts_pour_les_cremations_privees_grand_modele_unite" }] }, { file: "data:image/;base64,", name: "Sacs bleus", description: "Pour pièces anatomiques", id: 14, path: "", items: [{ name: "Standard", description: "Par 25", price: 0, functional_id: "sacs_bleus_pour_pieces_anatomiques_standard_par_25" }] }, { file: "data:image/;base64,", name: "Etiquettes d'identification", id: 15, path: "", items: [{ name: "Standard", description: "Par 50", price: 0, functional_id: "identification_et_colliers_de_serrages_standard_par_50" }] }, { file: "data:image/;base64,", name: "Colliers de serrages", id: 16, path: "", items: [{ name: "Standard", description: "Par 50", price: 0, functional_id: "distributeurs_pour_sacs_housse_par_5" }] }], sorting: 2300 }],
        cartObject = Object.fromEntries(cart.map(({ functional_id, quantity }) => [functional_id, quantity])),
        result = market.reduce((r, booth) => {
            var products = booth.products.reduce((s, product) => {
                var items = product.items.reduce((t, item) => {
                    if (item.functional_id in cartObject) t.push({ ...item, quantity: cartObject[item.functional_id] });
                    return t;
                }, []);
                if (items.length) s.push({ ...product, items });
                return s;
            }, []);
            if (products.length) r.push({ ...booth, products });
            return r;
        }, []);
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }