0

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

3
  • 1
    I'd probably use recursion in this situation. A function which calls its self as it finds more nested objects inside it. Passing a top parameter of the first array which you can then test against it. I'll mock an example. Commented Jun 5, 2020 at 11:04
  • 1
    where do you get 'etiquettes_identification_et_colliers_de_serrages_standard_par_50' from? it is not in the data ... Commented Jun 5, 2020 at 11:23
  • @NinaScholz Sorry, I just corrected it, by copying and pasting I must have made a mistake Commented Jun 5, 2020 at 11:31

4 Answers 4

1

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

Sign up to request clarification or add additional context in comments.

Comments

1

You can do it without recursion if you know how deep your nesting is up front, and it won't change. (Recursion would offer a more general solution):

  • I do it by creating a cart lookupItems Object (with reduce) for fast lookups later
  • then map over markets
    • then map over products
      • then filter items for those that are in the cart lookupItems Object
    • then filter any products out whose items array have length == 0
  • then filter any markets out whose products array have length == 0

Note: you appear to have an inconsistency, I had to modify your cart to get the expected output, specifically this item ("etiquettes_" was added to the front of the "functional_id" but in your market data it just 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_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
}
];
</script>

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
          }
        ]
      }
    ]
  },
  {
    "name": "Documents",
    "products": [
      {
        "file": "data:image/;base64,",
        "name": "Carnet de conventions",
        "id": 17,
        "path": "",
        "items": [
          {
            "price": 0,
            "functional_id": "carnet_de_conventions",
            "quantity": 3
          }
        ]
      }
    ]
  },
  {
    "name": "Matériel crémation",
    "products": [
      {
        "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",
            "quantity": 2
          }
        ]
      }
    ]
  }
]

Comments

1

Using flatMap to add quantity and filter out non-match. Using destructuring to exclude properties not wanted in the outputted object.

cartMap = {}
cart.forEach(({ functional_id: id, quantity }) => cartMap[id] = !quantity || {quantity})
// true if undefined, else {quantity}, so I don't try to overwrite 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",
    // is this a 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": [{
        "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
  }
]
</script>
</head>

Comments

1

Ok just updated: This has been tested so should work now. This will check against any child which has an array then try to match the object from cart to each nest. If you dont want to match quantity - replace out my function as I've commented below

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" }] }, { 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 }];

const isMatchKeys = (obj, cur, keys) => (
  keys.every(key => (
    obj[key] === cur[key]
)));

const matchAllNested = (obj, arrNest, keys, parent = null) => (
  Array.isArray(arrNest) && arrNest.reduce((accum, cur) => {
    const top = parent || cur;
    return accum || (isMatchKeys(obj, cur, keys) && top) || findInEachNested(obj, cur, keys, top);
  }, null)
);

const findInEachNested = (obj, objNest, keys, parent) => (
  Object.keys(objNest).reduce((accum, cur) => (
    accum || Array.isArray(objNest[cur]) && matchAllNested(obj, objNest[cur], keys, parent)
  ), null)
);

const finalArray = cart.map(obj => (
  matchAllNested(obj, market, ['functional_id'])
));

console.log(finalArray);

Output:

[
  {
    "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": "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
  },
  {
    "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
  }
]

5 Comments

Hey @steve looks like a beautiful solution. I added the input data and made it a snippet, so that I (and everyone else) could see your output. But this doesn't look as expected?
oh. Show me the output. I've added a code snippet above.
I added your output, you can also click "Run code snippet" and you will see the same in the console. The OP wants to filter down to essentially only the parents of those 3 "functional_id"s from the cart. But it looks like your output contains many more items?
Oh maybe i misinterpreted your requirement. To return the top object if any of its children match functional_id.
check out the "desired output" from the question, I think it can be described as "show only those items that match the functional_id, and for those, show them with their parent(s)".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.