Merge two arrays of objects by ID












-3















I have two arrays like this:



let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];


Now I want a result like this:



result = [ {name: "apple", prices: [{id: 1, price: 50}, {id: 1, price: 40}]}, {name: "orange", prices: [{id: 2, price: 30}]}, {name: "others", prices: [{id: null, price: 80}]}] 


I want to map the elements of the array a to the name of the second array b on the basis of their ids.










share|improve this question

























  • is the result for apple's prices supposed to be [{id: 1, price: 50}, {id: 1, price: 40}] instead?

    – Shawn Andrews
    Nov 24 '18 at 21:36













  • this is just an example of the real problem i have. i did give a bad example but yes i want exactly what i wrote.

    – Nitesh Ranjan
    Nov 24 '18 at 21:37













  • im confused by the result. you say you want a to map to b on the basis of their ids, but {id: 1, price: 40} in a maps to "apple" but its not in the apple object in your result?

    – Shawn Andrews
    Nov 24 '18 at 21:45











  • Why would you want to repeat the id with each price? Certainly the id will be the same for the prices that appear in the same array. It seems more appropriate to avoid this repetition, and put the id at the name level in your output structure.

    – trincot
    Nov 24 '18 at 22:12











  • Any feed-back on my comment, and on the answers below?

    – trincot
    Nov 25 '18 at 19:29
















-3















I have two arrays like this:



let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];


Now I want a result like this:



result = [ {name: "apple", prices: [{id: 1, price: 50}, {id: 1, price: 40}]}, {name: "orange", prices: [{id: 2, price: 30}]}, {name: "others", prices: [{id: null, price: 80}]}] 


I want to map the elements of the array a to the name of the second array b on the basis of their ids.










share|improve this question

























  • is the result for apple's prices supposed to be [{id: 1, price: 50}, {id: 1, price: 40}] instead?

    – Shawn Andrews
    Nov 24 '18 at 21:36













  • this is just an example of the real problem i have. i did give a bad example but yes i want exactly what i wrote.

    – Nitesh Ranjan
    Nov 24 '18 at 21:37













  • im confused by the result. you say you want a to map to b on the basis of their ids, but {id: 1, price: 40} in a maps to "apple" but its not in the apple object in your result?

    – Shawn Andrews
    Nov 24 '18 at 21:45











  • Why would you want to repeat the id with each price? Certainly the id will be the same for the prices that appear in the same array. It seems more appropriate to avoid this repetition, and put the id at the name level in your output structure.

    – trincot
    Nov 24 '18 at 22:12











  • Any feed-back on my comment, and on the answers below?

    – trincot
    Nov 25 '18 at 19:29














-3












-3








-3


0






I have two arrays like this:



let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];


Now I want a result like this:



result = [ {name: "apple", prices: [{id: 1, price: 50}, {id: 1, price: 40}]}, {name: "orange", prices: [{id: 2, price: 30}]}, {name: "others", prices: [{id: null, price: 80}]}] 


I want to map the elements of the array a to the name of the second array b on the basis of their ids.










share|improve this question
















I have two arrays like this:



let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];


Now I want a result like this:



result = [ {name: "apple", prices: [{id: 1, price: 50}, {id: 1, price: 40}]}, {name: "orange", prices: [{id: 2, price: 30}]}, {name: "others", prices: [{id: null, price: 80}]}] 


I want to map the elements of the array a to the name of the second array b on the basis of their ids.







javascript arrays json reactjs






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 25 '18 at 8:22







Nitesh Ranjan

















asked Nov 24 '18 at 21:30









Nitesh RanjanNitesh Ranjan

10116




10116













  • is the result for apple's prices supposed to be [{id: 1, price: 50}, {id: 1, price: 40}] instead?

    – Shawn Andrews
    Nov 24 '18 at 21:36













  • this is just an example of the real problem i have. i did give a bad example but yes i want exactly what i wrote.

    – Nitesh Ranjan
    Nov 24 '18 at 21:37













  • im confused by the result. you say you want a to map to b on the basis of their ids, but {id: 1, price: 40} in a maps to "apple" but its not in the apple object in your result?

    – Shawn Andrews
    Nov 24 '18 at 21:45











  • Why would you want to repeat the id with each price? Certainly the id will be the same for the prices that appear in the same array. It seems more appropriate to avoid this repetition, and put the id at the name level in your output structure.

    – trincot
    Nov 24 '18 at 22:12











  • Any feed-back on my comment, and on the answers below?

    – trincot
    Nov 25 '18 at 19:29



















  • is the result for apple's prices supposed to be [{id: 1, price: 50}, {id: 1, price: 40}] instead?

    – Shawn Andrews
    Nov 24 '18 at 21:36













  • this is just an example of the real problem i have. i did give a bad example but yes i want exactly what i wrote.

    – Nitesh Ranjan
    Nov 24 '18 at 21:37













  • im confused by the result. you say you want a to map to b on the basis of their ids, but {id: 1, price: 40} in a maps to "apple" but its not in the apple object in your result?

    – Shawn Andrews
    Nov 24 '18 at 21:45











  • Why would you want to repeat the id with each price? Certainly the id will be the same for the prices that appear in the same array. It seems more appropriate to avoid this repetition, and put the id at the name level in your output structure.

    – trincot
    Nov 24 '18 at 22:12











  • Any feed-back on my comment, and on the answers below?

    – trincot
    Nov 25 '18 at 19:29

















is the result for apple's prices supposed to be [{id: 1, price: 50}, {id: 1, price: 40}] instead?

– Shawn Andrews
Nov 24 '18 at 21:36







is the result for apple's prices supposed to be [{id: 1, price: 50}, {id: 1, price: 40}] instead?

– Shawn Andrews
Nov 24 '18 at 21:36















this is just an example of the real problem i have. i did give a bad example but yes i want exactly what i wrote.

– Nitesh Ranjan
Nov 24 '18 at 21:37







this is just an example of the real problem i have. i did give a bad example but yes i want exactly what i wrote.

– Nitesh Ranjan
Nov 24 '18 at 21:37















im confused by the result. you say you want a to map to b on the basis of their ids, but {id: 1, price: 40} in a maps to "apple" but its not in the apple object in your result?

– Shawn Andrews
Nov 24 '18 at 21:45





im confused by the result. you say you want a to map to b on the basis of their ids, but {id: 1, price: 40} in a maps to "apple" but its not in the apple object in your result?

– Shawn Andrews
Nov 24 '18 at 21:45













Why would you want to repeat the id with each price? Certainly the id will be the same for the prices that appear in the same array. It seems more appropriate to avoid this repetition, and put the id at the name level in your output structure.

– trincot
Nov 24 '18 at 22:12





Why would you want to repeat the id with each price? Certainly the id will be the same for the prices that appear in the same array. It seems more appropriate to avoid this repetition, and put the id at the name level in your output structure.

– trincot
Nov 24 '18 at 22:12













Any feed-back on my comment, and on the answers below?

– trincot
Nov 25 '18 at 19:29





Any feed-back on my comment, and on the answers below?

– trincot
Nov 25 '18 at 19:29












4 Answers
4






active

oldest

votes


















1














Here's an approach that using reduce to build a lookup set and avoid repeated searches in b. Another reduction pass builds the result arrays by name using the lookup table. Lastly, map is used to format the result.



Time complexity is linear (three passes with a lot of constant time object lookups).






let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

const lookup = b.reduce((a, e) => {
a[e.id] = e.name;
return a;
}, {});

const result = Object.entries(
a.reduce((a, e) => {
const key = lookup[e.id] || "others";

if (!(key in a)) {
a[key] = ;
}

a[key].push(e);
return a;
}, {})
).map(e => ({name: e[0], prices: e[1]}));

console.log(result);








share|improve this answer

































    1














    It would be more logical to not repeat the id in the prices part of the result, since the id belongs with the name.



    I would suggest using a temporary map (for efficiency):






    let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
    let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

    const map = new Map(b.map(o => [o.id, Object.assign(o, { prices: })]))
    .set(null, {id: null, name: "others", prices: });

    a.forEach(o => map.get(o.id).prices.push(o.price));

    const result = [...map.values()];

    console.log(result);








    share|improve this answer































      1














      Yes, you can do it simply with a map and a filter



      let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
      let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

      b.map(({ name, id }) => ({
      name,
      id,
      prices: a.filter(item => item.id === id).map(({ price }) => price)
      }));





      share|improve this answer



















      • 1





        map*filter = O(n²).

        – trincot
        Nov 24 '18 at 22:13





















      1














      You can do this with a single Array.reduce and Object.values if you start by combining the 2 arrays together:






      let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
      let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

      const result = Object.values([...b, ...a].reduce((r, c) => {
      if ('name' in c || c.id == null)
      r[c.id || 'others'] = ({name: c.name || 'others', prices: })

      if ('name' in c)
      return r
      else if (c.id != null)
      r[c.id].prices.push(c)
      else
      r['others'].prices.push(c)
      return r
      }, {}))

      console.log(result)





      The idea is to start with the one containing the names so the grouping creates first the object groupings and then just fill the group arrays.






      share|improve this answer

























        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53462526%2fmerge-two-arrays-of-objects-by-id%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        1














        Here's an approach that using reduce to build a lookup set and avoid repeated searches in b. Another reduction pass builds the result arrays by name using the lookup table. Lastly, map is used to format the result.



        Time complexity is linear (three passes with a lot of constant time object lookups).






        let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
        let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

        const lookup = b.reduce((a, e) => {
        a[e.id] = e.name;
        return a;
        }, {});

        const result = Object.entries(
        a.reduce((a, e) => {
        const key = lookup[e.id] || "others";

        if (!(key in a)) {
        a[key] = ;
        }

        a[key].push(e);
        return a;
        }, {})
        ).map(e => ({name: e[0], prices: e[1]}));

        console.log(result);








        share|improve this answer






























          1














          Here's an approach that using reduce to build a lookup set and avoid repeated searches in b. Another reduction pass builds the result arrays by name using the lookup table. Lastly, map is used to format the result.



          Time complexity is linear (three passes with a lot of constant time object lookups).






          let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
          let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

          const lookup = b.reduce((a, e) => {
          a[e.id] = e.name;
          return a;
          }, {});

          const result = Object.entries(
          a.reduce((a, e) => {
          const key = lookup[e.id] || "others";

          if (!(key in a)) {
          a[key] = ;
          }

          a[key].push(e);
          return a;
          }, {})
          ).map(e => ({name: e[0], prices: e[1]}));

          console.log(result);








          share|improve this answer




























            1












            1








            1







            Here's an approach that using reduce to build a lookup set and avoid repeated searches in b. Another reduction pass builds the result arrays by name using the lookup table. Lastly, map is used to format the result.



            Time complexity is linear (three passes with a lot of constant time object lookups).






            let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
            let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

            const lookup = b.reduce((a, e) => {
            a[e.id] = e.name;
            return a;
            }, {});

            const result = Object.entries(
            a.reduce((a, e) => {
            const key = lookup[e.id] || "others";

            if (!(key in a)) {
            a[key] = ;
            }

            a[key].push(e);
            return a;
            }, {})
            ).map(e => ({name: e[0], prices: e[1]}));

            console.log(result);








            share|improve this answer















            Here's an approach that using reduce to build a lookup set and avoid repeated searches in b. Another reduction pass builds the result arrays by name using the lookup table. Lastly, map is used to format the result.



            Time complexity is linear (three passes with a lot of constant time object lookups).






            let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
            let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

            const lookup = b.reduce((a, e) => {
            a[e.id] = e.name;
            return a;
            }, {});

            const result = Object.entries(
            a.reduce((a, e) => {
            const key = lookup[e.id] || "others";

            if (!(key in a)) {
            a[key] = ;
            }

            a[key].push(e);
            return a;
            }, {})
            ).map(e => ({name: e[0], prices: e[1]}));

            console.log(result);








            let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
            let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

            const lookup = b.reduce((a, e) => {
            a[e.id] = e.name;
            return a;
            }, {});

            const result = Object.entries(
            a.reduce((a, e) => {
            const key = lookup[e.id] || "others";

            if (!(key in a)) {
            a[key] = ;
            }

            a[key].push(e);
            return a;
            }, {})
            ).map(e => ({name: e[0], prices: e[1]}));

            console.log(result);





            let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
            let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

            const lookup = b.reduce((a, e) => {
            a[e.id] = e.name;
            return a;
            }, {});

            const result = Object.entries(
            a.reduce((a, e) => {
            const key = lookup[e.id] || "others";

            if (!(key in a)) {
            a[key] = ;
            }

            a[key].push(e);
            return a;
            }, {})
            ).map(e => ({name: e[0], prices: e[1]}));

            console.log(result);






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 24 '18 at 22:03

























            answered Nov 24 '18 at 21:52









            ggorlenggorlen

            7,1883825




            7,1883825

























                1














                It would be more logical to not repeat the id in the prices part of the result, since the id belongs with the name.



                I would suggest using a temporary map (for efficiency):






                let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                const map = new Map(b.map(o => [o.id, Object.assign(o, { prices: })]))
                .set(null, {id: null, name: "others", prices: });

                a.forEach(o => map.get(o.id).prices.push(o.price));

                const result = [...map.values()];

                console.log(result);








                share|improve this answer




























                  1














                  It would be more logical to not repeat the id in the prices part of the result, since the id belongs with the name.



                  I would suggest using a temporary map (for efficiency):






                  let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                  let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                  const map = new Map(b.map(o => [o.id, Object.assign(o, { prices: })]))
                  .set(null, {id: null, name: "others", prices: });

                  a.forEach(o => map.get(o.id).prices.push(o.price));

                  const result = [...map.values()];

                  console.log(result);








                  share|improve this answer


























                    1












                    1








                    1







                    It would be more logical to not repeat the id in the prices part of the result, since the id belongs with the name.



                    I would suggest using a temporary map (for efficiency):






                    let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                    let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                    const map = new Map(b.map(o => [o.id, Object.assign(o, { prices: })]))
                    .set(null, {id: null, name: "others", prices: });

                    a.forEach(o => map.get(o.id).prices.push(o.price));

                    const result = [...map.values()];

                    console.log(result);








                    share|improve this answer













                    It would be more logical to not repeat the id in the prices part of the result, since the id belongs with the name.



                    I would suggest using a temporary map (for efficiency):






                    let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                    let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                    const map = new Map(b.map(o => [o.id, Object.assign(o, { prices: })]))
                    .set(null, {id: null, name: "others", prices: });

                    a.forEach(o => map.get(o.id).prices.push(o.price));

                    const result = [...map.values()];

                    console.log(result);








                    let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                    let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                    const map = new Map(b.map(o => [o.id, Object.assign(o, { prices: })]))
                    .set(null, {id: null, name: "others", prices: });

                    a.forEach(o => map.get(o.id).prices.push(o.price));

                    const result = [...map.values()];

                    console.log(result);





                    let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                    let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                    const map = new Map(b.map(o => [o.id, Object.assign(o, { prices: })]))
                    .set(null, {id: null, name: "others", prices: });

                    a.forEach(o => map.get(o.id).prices.push(o.price));

                    const result = [...map.values()];

                    console.log(result);






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 24 '18 at 22:11









                    trincottrincot

                    125k1588121




                    125k1588121























                        1














                        Yes, you can do it simply with a map and a filter



                        let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                        let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                        b.map(({ name, id }) => ({
                        name,
                        id,
                        prices: a.filter(item => item.id === id).map(({ price }) => price)
                        }));





                        share|improve this answer



















                        • 1





                          map*filter = O(n²).

                          – trincot
                          Nov 24 '18 at 22:13


















                        1














                        Yes, you can do it simply with a map and a filter



                        let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                        let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                        b.map(({ name, id }) => ({
                        name,
                        id,
                        prices: a.filter(item => item.id === id).map(({ price }) => price)
                        }));





                        share|improve this answer



















                        • 1





                          map*filter = O(n²).

                          – trincot
                          Nov 24 '18 at 22:13
















                        1












                        1








                        1







                        Yes, you can do it simply with a map and a filter



                        let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                        let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                        b.map(({ name, id }) => ({
                        name,
                        id,
                        prices: a.filter(item => item.id === id).map(({ price }) => price)
                        }));





                        share|improve this answer













                        Yes, you can do it simply with a map and a filter



                        let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                        let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                        b.map(({ name, id }) => ({
                        name,
                        id,
                        prices: a.filter(item => item.id === id).map(({ price }) => price)
                        }));






                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Nov 24 '18 at 22:12









                        Andy RayAndy Ray

                        17.7k76298




                        17.7k76298








                        • 1





                          map*filter = O(n²).

                          – trincot
                          Nov 24 '18 at 22:13
















                        • 1





                          map*filter = O(n²).

                          – trincot
                          Nov 24 '18 at 22:13










                        1




                        1





                        map*filter = O(n²).

                        – trincot
                        Nov 24 '18 at 22:13







                        map*filter = O(n²).

                        – trincot
                        Nov 24 '18 at 22:13













                        1














                        You can do this with a single Array.reduce and Object.values if you start by combining the 2 arrays together:






                        let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                        let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                        const result = Object.values([...b, ...a].reduce((r, c) => {
                        if ('name' in c || c.id == null)
                        r[c.id || 'others'] = ({name: c.name || 'others', prices: })

                        if ('name' in c)
                        return r
                        else if (c.id != null)
                        r[c.id].prices.push(c)
                        else
                        r['others'].prices.push(c)
                        return r
                        }, {}))

                        console.log(result)





                        The idea is to start with the one containing the names so the grouping creates first the object groupings and then just fill the group arrays.






                        share|improve this answer






























                          1














                          You can do this with a single Array.reduce and Object.values if you start by combining the 2 arrays together:






                          let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                          let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                          const result = Object.values([...b, ...a].reduce((r, c) => {
                          if ('name' in c || c.id == null)
                          r[c.id || 'others'] = ({name: c.name || 'others', prices: })

                          if ('name' in c)
                          return r
                          else if (c.id != null)
                          r[c.id].prices.push(c)
                          else
                          r['others'].prices.push(c)
                          return r
                          }, {}))

                          console.log(result)





                          The idea is to start with the one containing the names so the grouping creates first the object groupings and then just fill the group arrays.






                          share|improve this answer




























                            1












                            1








                            1







                            You can do this with a single Array.reduce and Object.values if you start by combining the 2 arrays together:






                            let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                            let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                            const result = Object.values([...b, ...a].reduce((r, c) => {
                            if ('name' in c || c.id == null)
                            r[c.id || 'others'] = ({name: c.name || 'others', prices: })

                            if ('name' in c)
                            return r
                            else if (c.id != null)
                            r[c.id].prices.push(c)
                            else
                            r['others'].prices.push(c)
                            return r
                            }, {}))

                            console.log(result)





                            The idea is to start with the one containing the names so the grouping creates first the object groupings and then just fill the group arrays.






                            share|improve this answer















                            You can do this with a single Array.reduce and Object.values if you start by combining the 2 arrays together:






                            let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                            let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                            const result = Object.values([...b, ...a].reduce((r, c) => {
                            if ('name' in c || c.id == null)
                            r[c.id || 'others'] = ({name: c.name || 'others', prices: })

                            if ('name' in c)
                            return r
                            else if (c.id != null)
                            r[c.id].prices.push(c)
                            else
                            r['others'].prices.push(c)
                            return r
                            }, {}))

                            console.log(result)





                            The idea is to start with the one containing the names so the grouping creates first the object groupings and then just fill the group arrays.






                            let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                            let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                            const result = Object.values([...b, ...a].reduce((r, c) => {
                            if ('name' in c || c.id == null)
                            r[c.id || 'others'] = ({name: c.name || 'others', prices: })

                            if ('name' in c)
                            return r
                            else if (c.id != null)
                            r[c.id].prices.push(c)
                            else
                            r['others'].prices.push(c)
                            return r
                            }, {}))

                            console.log(result)





                            let a = [{id: 1, price: 50}, {id: 2, price: 30}, {id: 1, price: 40}, {id: null, price: 80}];
                            let b = [{id: 1, name: "apple"}, {id: 2, name: "orange"}];

                            const result = Object.values([...b, ...a].reduce((r, c) => {
                            if ('name' in c || c.id == null)
                            r[c.id || 'others'] = ({name: c.name || 'others', prices: })

                            if ('name' in c)
                            return r
                            else if (c.id != null)
                            r[c.id].prices.push(c)
                            else
                            r['others'].prices.push(c)
                            return r
                            }, {}))

                            console.log(result)






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Nov 25 '18 at 2:11

























                            answered Nov 25 '18 at 0:21









                            AkrionAkrion

                            9,48511224




                            9,48511224






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53462526%2fmerge-two-arrays-of-objects-by-id%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Futebolista

                                Feedback on college project

                                Albești (Vaslui)