Javascript remove duplicate in a list of objects merging some properties











up vote
0
down vote

favorite












I have this list:



const debts = [
{
amount: 10,
debtor: "Mark",
creditor: "John"
},
{
amount: 20,
debtor: "Mark",
creditor: "John"
},
{
amount: 10,
debtor: "Mark",
creditor: "Tom"
}
];


...and I want to merge the elements with the same debtor and creditor calculating the total amount, like this



const debts = [
{
amount: 30, // 10 + 20
debtor: "Mark",
creditor: "John"
},
{
amount: 10,
debtor: "Mark",
creditor: "Tom"
}
];


Could anyone help me? Thanks










share|improve this question


























    up vote
    0
    down vote

    favorite












    I have this list:



    const debts = [
    {
    amount: 10,
    debtor: "Mark",
    creditor: "John"
    },
    {
    amount: 20,
    debtor: "Mark",
    creditor: "John"
    },
    {
    amount: 10,
    debtor: "Mark",
    creditor: "Tom"
    }
    ];


    ...and I want to merge the elements with the same debtor and creditor calculating the total amount, like this



    const debts = [
    {
    amount: 30, // 10 + 20
    debtor: "Mark",
    creditor: "John"
    },
    {
    amount: 10,
    debtor: "Mark",
    creditor: "Tom"
    }
    ];


    Could anyone help me? Thanks










    share|improve this question
























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I have this list:



      const debts = [
      {
      amount: 10,
      debtor: "Mark",
      creditor: "John"
      },
      {
      amount: 20,
      debtor: "Mark",
      creditor: "John"
      },
      {
      amount: 10,
      debtor: "Mark",
      creditor: "Tom"
      }
      ];


      ...and I want to merge the elements with the same debtor and creditor calculating the total amount, like this



      const debts = [
      {
      amount: 30, // 10 + 20
      debtor: "Mark",
      creditor: "John"
      },
      {
      amount: 10,
      debtor: "Mark",
      creditor: "Tom"
      }
      ];


      Could anyone help me? Thanks










      share|improve this question













      I have this list:



      const debts = [
      {
      amount: 10,
      debtor: "Mark",
      creditor: "John"
      },
      {
      amount: 20,
      debtor: "Mark",
      creditor: "John"
      },
      {
      amount: 10,
      debtor: "Mark",
      creditor: "Tom"
      }
      ];


      ...and I want to merge the elements with the same debtor and creditor calculating the total amount, like this



      const debts = [
      {
      amount: 30, // 10 + 20
      debtor: "Mark",
      creditor: "John"
      },
      {
      amount: 10,
      debtor: "Mark",
      creditor: "Tom"
      }
      ];


      Could anyone help me? Thanks







      javascript arrays lodash ramda.js






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked yesterday









      SergioP

      304




      304
























          3 Answers
          3






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          If you're interested in a solution using Ramda, here's a suggestion:






          const {
          pipe,
          mergeWithKey,
          map,
          reduce,
          values,
          groupBy,
          props,
          join
          } = R;

          const debts = [{
          amount: 10,
          debtor: "Mark",
          creditor: "John"
          },
          {
          amount: 20,
          debtor: "Mark",
          creditor: "John"
          },
          {
          amount: 10,
          debtor: "Mark",
          creditor: "Tom"
          }
          ];

          const mergeAmount = mergeWithKey((key, left, right) => key === 'amount' ? left + right : left);
          const groupKey = pipe(props(['debtor', 'creditor']), join(' ~> '));

          const process =
          pipe(
          groupBy(groupKey),
          map(reduce(mergeAmount, {})),
          values);

          console.log(process(debts));

          <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>







          The idea is to split the process in three steps:




          1. Group debtors and creditors together

          2. For each debtor/creditor group, merge the amount

          3. Extract each debtor/creditor group into an array


          Step 1: groupBy(groupKey)



          Step 1 gets the original debts array



          {
          "Mark ~> John": [
          {
          amount: 10,
          creditor: "John",
          debtor: "Mark"
          },
          {
          amount: 20,
          creditor: "John",
          debtor: "Mark"
          }
          ],
          "Mark ~> Tom": [
          {
          amount: 10,
          creditor: "Tom",
          debtor: "Mark"
          }
          ]
          }


          Step 2: map(reduce(mergeAmount, {}))



          Step 2 gets the output from step 1



          {
          "Mark ~> John": {
          amount: 30,
          creditor: "John",
          debtor: "Mark"
          },
          "Mark ~> Tom": {
          amount: 10,
          creditor: "Tom",
          debtor: "Mark"
          }
          }


          Step 3: values



          Step 3 gets the output from step 2



          [
          {
          amount: 30,
          creditor: "John",
          debtor: "Mark"
          },
          {
          amount: 10,
          creditor: "Tom",
          debtor: "Mark"
          }
          ]





          share|improve this answer























          • Slightly cleaner, perhaps, would be map(reduce(mergeAmount, {amount: 0})) for the second step.
            – Scott Sauyet
            yesterday






          • 1




            Interesting, as my own solution was almost identical except for the comment above and the inlining of what you call groupKey. And, this is very interesting, I invert the order of your last two steps; it works either way. I actually think Ramda needs a function something like (fn) => (list) => values(groupBy(fn, list)). It's such a common combination.
            – Scott Sauyet
            yesterday






          • 2




            You can convert map(reduce(mergeAmount, {amount: 0})) to map(reduce(mergeAmount, {})) because if the key doesn't exist in both mergeWithKey doesn't use the callback.
            – Ori Drori
            yesterday








          • 1




            @OriDrori: Oh, right, that's better.
            – Scott Sauyet
            yesterday






          • 1




            Oh thanks @OriDrori :-) I have edited the answer accordingly.
            – customcommander
            yesterday


















          up vote
          2
          down vote













          You can use Array.reduce to create an object with key as unique pair of debtor and creditor and value as resulting object. In case there is an existing entry for the pair in object, increment the amount else add a new entry in object.



          Finally, use Object.values to collect all the objects.






          let debts = [{amount: 10,debtor: "Mark",creditor: "John"},{amount: 20,debtor: "Mark",creditor: "John"},{amount: 10,debtor: "Mark",creditor: "Tom"}];

          let result = Object.values(debts.reduce((a,c) => {
          let key = `${c.debtor}~~${c.creditor}`;
          if(a[key]) a[key].amount += c.amount;
          else a[key] = Object.assign({},c);
          return a;
          }, {}));
          console.log(result);








          share|improve this answer





















          • Looks great, why do you used a[key] = Object.assign({},c) instead of a[key] = c?
            – SergioP
            yesterday










          • @SergioP - Objects are passed by reference and whenever a[key].amount += c.amount; the object is modified. I wanted to avoid overwriting the object in the array
            – Nikhil Aggarwal
            yesterday








          • 1




            Thanks for the explanation. :-)
            – SergioP
            yesterday




















          up vote
          1
          down vote













          Use the filter() function to iterate through the resulting list and check if the debtor-creditor pair already exist. If it exists, then updates the amount. Otherwise, add it as a new entry in the resulting list.






          const debts = [
          {
          amount: 10,
          debtor: "Mark",
          creditor: "John"
          },
          {
          amount: 20,
          debtor: "Mark",
          creditor: "John"
          },
          {
          amount: 10,
          debtor: "Mark",
          creditor: "Tom"
          }
          ];

          var result =
          debts.forEach((item) => {
          var existing = result.filter((resultItem, index) => {
          return resultItem.debtor === item.debtor && resultItem.creditor === item.creditor;
          });

          if (existing.length) {
          var existingIndex = result.indexOf(existing[0]);
          result[existingIndex].amount += item.amount;
          } else {
          result.push(item);
          }
          })

          console.log(result)








          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',
            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%2f53372012%2fjavascript-remove-duplicate-in-a-list-of-objects-merging-some-properties%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            3
            down vote



            accepted










            If you're interested in a solution using Ramda, here's a suggestion:






            const {
            pipe,
            mergeWithKey,
            map,
            reduce,
            values,
            groupBy,
            props,
            join
            } = R;

            const debts = [{
            amount: 10,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 20,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 10,
            debtor: "Mark",
            creditor: "Tom"
            }
            ];

            const mergeAmount = mergeWithKey((key, left, right) => key === 'amount' ? left + right : left);
            const groupKey = pipe(props(['debtor', 'creditor']), join(' ~> '));

            const process =
            pipe(
            groupBy(groupKey),
            map(reduce(mergeAmount, {})),
            values);

            console.log(process(debts));

            <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>







            The idea is to split the process in three steps:




            1. Group debtors and creditors together

            2. For each debtor/creditor group, merge the amount

            3. Extract each debtor/creditor group into an array


            Step 1: groupBy(groupKey)



            Step 1 gets the original debts array



            {
            "Mark ~> John": [
            {
            amount: 10,
            creditor: "John",
            debtor: "Mark"
            },
            {
            amount: 20,
            creditor: "John",
            debtor: "Mark"
            }
            ],
            "Mark ~> Tom": [
            {
            amount: 10,
            creditor: "Tom",
            debtor: "Mark"
            }
            ]
            }


            Step 2: map(reduce(mergeAmount, {}))



            Step 2 gets the output from step 1



            {
            "Mark ~> John": {
            amount: 30,
            creditor: "John",
            debtor: "Mark"
            },
            "Mark ~> Tom": {
            amount: 10,
            creditor: "Tom",
            debtor: "Mark"
            }
            }


            Step 3: values



            Step 3 gets the output from step 2



            [
            {
            amount: 30,
            creditor: "John",
            debtor: "Mark"
            },
            {
            amount: 10,
            creditor: "Tom",
            debtor: "Mark"
            }
            ]





            share|improve this answer























            • Slightly cleaner, perhaps, would be map(reduce(mergeAmount, {amount: 0})) for the second step.
              – Scott Sauyet
              yesterday






            • 1




              Interesting, as my own solution was almost identical except for the comment above and the inlining of what you call groupKey. And, this is very interesting, I invert the order of your last two steps; it works either way. I actually think Ramda needs a function something like (fn) => (list) => values(groupBy(fn, list)). It's such a common combination.
              – Scott Sauyet
              yesterday






            • 2




              You can convert map(reduce(mergeAmount, {amount: 0})) to map(reduce(mergeAmount, {})) because if the key doesn't exist in both mergeWithKey doesn't use the callback.
              – Ori Drori
              yesterday








            • 1




              @OriDrori: Oh, right, that's better.
              – Scott Sauyet
              yesterday






            • 1




              Oh thanks @OriDrori :-) I have edited the answer accordingly.
              – customcommander
              yesterday















            up vote
            3
            down vote



            accepted










            If you're interested in a solution using Ramda, here's a suggestion:






            const {
            pipe,
            mergeWithKey,
            map,
            reduce,
            values,
            groupBy,
            props,
            join
            } = R;

            const debts = [{
            amount: 10,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 20,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 10,
            debtor: "Mark",
            creditor: "Tom"
            }
            ];

            const mergeAmount = mergeWithKey((key, left, right) => key === 'amount' ? left + right : left);
            const groupKey = pipe(props(['debtor', 'creditor']), join(' ~> '));

            const process =
            pipe(
            groupBy(groupKey),
            map(reduce(mergeAmount, {})),
            values);

            console.log(process(debts));

            <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>







            The idea is to split the process in three steps:




            1. Group debtors and creditors together

            2. For each debtor/creditor group, merge the amount

            3. Extract each debtor/creditor group into an array


            Step 1: groupBy(groupKey)



            Step 1 gets the original debts array



            {
            "Mark ~> John": [
            {
            amount: 10,
            creditor: "John",
            debtor: "Mark"
            },
            {
            amount: 20,
            creditor: "John",
            debtor: "Mark"
            }
            ],
            "Mark ~> Tom": [
            {
            amount: 10,
            creditor: "Tom",
            debtor: "Mark"
            }
            ]
            }


            Step 2: map(reduce(mergeAmount, {}))



            Step 2 gets the output from step 1



            {
            "Mark ~> John": {
            amount: 30,
            creditor: "John",
            debtor: "Mark"
            },
            "Mark ~> Tom": {
            amount: 10,
            creditor: "Tom",
            debtor: "Mark"
            }
            }


            Step 3: values



            Step 3 gets the output from step 2



            [
            {
            amount: 30,
            creditor: "John",
            debtor: "Mark"
            },
            {
            amount: 10,
            creditor: "Tom",
            debtor: "Mark"
            }
            ]





            share|improve this answer























            • Slightly cleaner, perhaps, would be map(reduce(mergeAmount, {amount: 0})) for the second step.
              – Scott Sauyet
              yesterday






            • 1




              Interesting, as my own solution was almost identical except for the comment above and the inlining of what you call groupKey. And, this is very interesting, I invert the order of your last two steps; it works either way. I actually think Ramda needs a function something like (fn) => (list) => values(groupBy(fn, list)). It's such a common combination.
              – Scott Sauyet
              yesterday






            • 2




              You can convert map(reduce(mergeAmount, {amount: 0})) to map(reduce(mergeAmount, {})) because if the key doesn't exist in both mergeWithKey doesn't use the callback.
              – Ori Drori
              yesterday








            • 1




              @OriDrori: Oh, right, that's better.
              – Scott Sauyet
              yesterday






            • 1




              Oh thanks @OriDrori :-) I have edited the answer accordingly.
              – customcommander
              yesterday













            up vote
            3
            down vote



            accepted







            up vote
            3
            down vote



            accepted






            If you're interested in a solution using Ramda, here's a suggestion:






            const {
            pipe,
            mergeWithKey,
            map,
            reduce,
            values,
            groupBy,
            props,
            join
            } = R;

            const debts = [{
            amount: 10,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 20,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 10,
            debtor: "Mark",
            creditor: "Tom"
            }
            ];

            const mergeAmount = mergeWithKey((key, left, right) => key === 'amount' ? left + right : left);
            const groupKey = pipe(props(['debtor', 'creditor']), join(' ~> '));

            const process =
            pipe(
            groupBy(groupKey),
            map(reduce(mergeAmount, {})),
            values);

            console.log(process(debts));

            <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>







            The idea is to split the process in three steps:




            1. Group debtors and creditors together

            2. For each debtor/creditor group, merge the amount

            3. Extract each debtor/creditor group into an array


            Step 1: groupBy(groupKey)



            Step 1 gets the original debts array



            {
            "Mark ~> John": [
            {
            amount: 10,
            creditor: "John",
            debtor: "Mark"
            },
            {
            amount: 20,
            creditor: "John",
            debtor: "Mark"
            }
            ],
            "Mark ~> Tom": [
            {
            amount: 10,
            creditor: "Tom",
            debtor: "Mark"
            }
            ]
            }


            Step 2: map(reduce(mergeAmount, {}))



            Step 2 gets the output from step 1



            {
            "Mark ~> John": {
            amount: 30,
            creditor: "John",
            debtor: "Mark"
            },
            "Mark ~> Tom": {
            amount: 10,
            creditor: "Tom",
            debtor: "Mark"
            }
            }


            Step 3: values



            Step 3 gets the output from step 2



            [
            {
            amount: 30,
            creditor: "John",
            debtor: "Mark"
            },
            {
            amount: 10,
            creditor: "Tom",
            debtor: "Mark"
            }
            ]





            share|improve this answer














            If you're interested in a solution using Ramda, here's a suggestion:






            const {
            pipe,
            mergeWithKey,
            map,
            reduce,
            values,
            groupBy,
            props,
            join
            } = R;

            const debts = [{
            amount: 10,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 20,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 10,
            debtor: "Mark",
            creditor: "Tom"
            }
            ];

            const mergeAmount = mergeWithKey((key, left, right) => key === 'amount' ? left + right : left);
            const groupKey = pipe(props(['debtor', 'creditor']), join(' ~> '));

            const process =
            pipe(
            groupBy(groupKey),
            map(reduce(mergeAmount, {})),
            values);

            console.log(process(debts));

            <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>







            The idea is to split the process in three steps:




            1. Group debtors and creditors together

            2. For each debtor/creditor group, merge the amount

            3. Extract each debtor/creditor group into an array


            Step 1: groupBy(groupKey)



            Step 1 gets the original debts array



            {
            "Mark ~> John": [
            {
            amount: 10,
            creditor: "John",
            debtor: "Mark"
            },
            {
            amount: 20,
            creditor: "John",
            debtor: "Mark"
            }
            ],
            "Mark ~> Tom": [
            {
            amount: 10,
            creditor: "Tom",
            debtor: "Mark"
            }
            ]
            }


            Step 2: map(reduce(mergeAmount, {}))



            Step 2 gets the output from step 1



            {
            "Mark ~> John": {
            amount: 30,
            creditor: "John",
            debtor: "Mark"
            },
            "Mark ~> Tom": {
            amount: 10,
            creditor: "Tom",
            debtor: "Mark"
            }
            }


            Step 3: values



            Step 3 gets the output from step 2



            [
            {
            amount: 30,
            creditor: "John",
            debtor: "Mark"
            },
            {
            amount: 10,
            creditor: "Tom",
            debtor: "Mark"
            }
            ]





            const {
            pipe,
            mergeWithKey,
            map,
            reduce,
            values,
            groupBy,
            props,
            join
            } = R;

            const debts = [{
            amount: 10,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 20,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 10,
            debtor: "Mark",
            creditor: "Tom"
            }
            ];

            const mergeAmount = mergeWithKey((key, left, right) => key === 'amount' ? left + right : left);
            const groupKey = pipe(props(['debtor', 'creditor']), join(' ~> '));

            const process =
            pipe(
            groupBy(groupKey),
            map(reduce(mergeAmount, {})),
            values);

            console.log(process(debts));

            <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>





            const {
            pipe,
            mergeWithKey,
            map,
            reduce,
            values,
            groupBy,
            props,
            join
            } = R;

            const debts = [{
            amount: 10,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 20,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 10,
            debtor: "Mark",
            creditor: "Tom"
            }
            ];

            const mergeAmount = mergeWithKey((key, left, right) => key === 'amount' ? left + right : left);
            const groupKey = pipe(props(['debtor', 'creditor']), join(' ~> '));

            const process =
            pipe(
            groupBy(groupKey),
            map(reduce(mergeAmount, {})),
            values);

            console.log(process(debts));

            <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited yesterday

























            answered yesterday









            customcommander

            555213




            555213












            • Slightly cleaner, perhaps, would be map(reduce(mergeAmount, {amount: 0})) for the second step.
              – Scott Sauyet
              yesterday






            • 1




              Interesting, as my own solution was almost identical except for the comment above and the inlining of what you call groupKey. And, this is very interesting, I invert the order of your last two steps; it works either way. I actually think Ramda needs a function something like (fn) => (list) => values(groupBy(fn, list)). It's such a common combination.
              – Scott Sauyet
              yesterday






            • 2




              You can convert map(reduce(mergeAmount, {amount: 0})) to map(reduce(mergeAmount, {})) because if the key doesn't exist in both mergeWithKey doesn't use the callback.
              – Ori Drori
              yesterday








            • 1




              @OriDrori: Oh, right, that's better.
              – Scott Sauyet
              yesterday






            • 1




              Oh thanks @OriDrori :-) I have edited the answer accordingly.
              – customcommander
              yesterday


















            • Slightly cleaner, perhaps, would be map(reduce(mergeAmount, {amount: 0})) for the second step.
              – Scott Sauyet
              yesterday






            • 1




              Interesting, as my own solution was almost identical except for the comment above and the inlining of what you call groupKey. And, this is very interesting, I invert the order of your last two steps; it works either way. I actually think Ramda needs a function something like (fn) => (list) => values(groupBy(fn, list)). It's such a common combination.
              – Scott Sauyet
              yesterday






            • 2




              You can convert map(reduce(mergeAmount, {amount: 0})) to map(reduce(mergeAmount, {})) because if the key doesn't exist in both mergeWithKey doesn't use the callback.
              – Ori Drori
              yesterday








            • 1




              @OriDrori: Oh, right, that's better.
              – Scott Sauyet
              yesterday






            • 1




              Oh thanks @OriDrori :-) I have edited the answer accordingly.
              – customcommander
              yesterday
















            Slightly cleaner, perhaps, would be map(reduce(mergeAmount, {amount: 0})) for the second step.
            – Scott Sauyet
            yesterday




            Slightly cleaner, perhaps, would be map(reduce(mergeAmount, {amount: 0})) for the second step.
            – Scott Sauyet
            yesterday




            1




            1




            Interesting, as my own solution was almost identical except for the comment above and the inlining of what you call groupKey. And, this is very interesting, I invert the order of your last two steps; it works either way. I actually think Ramda needs a function something like (fn) => (list) => values(groupBy(fn, list)). It's such a common combination.
            – Scott Sauyet
            yesterday




            Interesting, as my own solution was almost identical except for the comment above and the inlining of what you call groupKey. And, this is very interesting, I invert the order of your last two steps; it works either way. I actually think Ramda needs a function something like (fn) => (list) => values(groupBy(fn, list)). It's such a common combination.
            – Scott Sauyet
            yesterday




            2




            2




            You can convert map(reduce(mergeAmount, {amount: 0})) to map(reduce(mergeAmount, {})) because if the key doesn't exist in both mergeWithKey doesn't use the callback.
            – Ori Drori
            yesterday






            You can convert map(reduce(mergeAmount, {amount: 0})) to map(reduce(mergeAmount, {})) because if the key doesn't exist in both mergeWithKey doesn't use the callback.
            – Ori Drori
            yesterday






            1




            1




            @OriDrori: Oh, right, that's better.
            – Scott Sauyet
            yesterday




            @OriDrori: Oh, right, that's better.
            – Scott Sauyet
            yesterday




            1




            1




            Oh thanks @OriDrori :-) I have edited the answer accordingly.
            – customcommander
            yesterday




            Oh thanks @OriDrori :-) I have edited the answer accordingly.
            – customcommander
            yesterday












            up vote
            2
            down vote













            You can use Array.reduce to create an object with key as unique pair of debtor and creditor and value as resulting object. In case there is an existing entry for the pair in object, increment the amount else add a new entry in object.



            Finally, use Object.values to collect all the objects.






            let debts = [{amount: 10,debtor: "Mark",creditor: "John"},{amount: 20,debtor: "Mark",creditor: "John"},{amount: 10,debtor: "Mark",creditor: "Tom"}];

            let result = Object.values(debts.reduce((a,c) => {
            let key = `${c.debtor}~~${c.creditor}`;
            if(a[key]) a[key].amount += c.amount;
            else a[key] = Object.assign({},c);
            return a;
            }, {}));
            console.log(result);








            share|improve this answer





















            • Looks great, why do you used a[key] = Object.assign({},c) instead of a[key] = c?
              – SergioP
              yesterday










            • @SergioP - Objects are passed by reference and whenever a[key].amount += c.amount; the object is modified. I wanted to avoid overwriting the object in the array
              – Nikhil Aggarwal
              yesterday








            • 1




              Thanks for the explanation. :-)
              – SergioP
              yesterday

















            up vote
            2
            down vote













            You can use Array.reduce to create an object with key as unique pair of debtor and creditor and value as resulting object. In case there is an existing entry for the pair in object, increment the amount else add a new entry in object.



            Finally, use Object.values to collect all the objects.






            let debts = [{amount: 10,debtor: "Mark",creditor: "John"},{amount: 20,debtor: "Mark",creditor: "John"},{amount: 10,debtor: "Mark",creditor: "Tom"}];

            let result = Object.values(debts.reduce((a,c) => {
            let key = `${c.debtor}~~${c.creditor}`;
            if(a[key]) a[key].amount += c.amount;
            else a[key] = Object.assign({},c);
            return a;
            }, {}));
            console.log(result);








            share|improve this answer





















            • Looks great, why do you used a[key] = Object.assign({},c) instead of a[key] = c?
              – SergioP
              yesterday










            • @SergioP - Objects are passed by reference and whenever a[key].amount += c.amount; the object is modified. I wanted to avoid overwriting the object in the array
              – Nikhil Aggarwal
              yesterday








            • 1




              Thanks for the explanation. :-)
              – SergioP
              yesterday















            up vote
            2
            down vote










            up vote
            2
            down vote









            You can use Array.reduce to create an object with key as unique pair of debtor and creditor and value as resulting object. In case there is an existing entry for the pair in object, increment the amount else add a new entry in object.



            Finally, use Object.values to collect all the objects.






            let debts = [{amount: 10,debtor: "Mark",creditor: "John"},{amount: 20,debtor: "Mark",creditor: "John"},{amount: 10,debtor: "Mark",creditor: "Tom"}];

            let result = Object.values(debts.reduce((a,c) => {
            let key = `${c.debtor}~~${c.creditor}`;
            if(a[key]) a[key].amount += c.amount;
            else a[key] = Object.assign({},c);
            return a;
            }, {}));
            console.log(result);








            share|improve this answer












            You can use Array.reduce to create an object with key as unique pair of debtor and creditor and value as resulting object. In case there is an existing entry for the pair in object, increment the amount else add a new entry in object.



            Finally, use Object.values to collect all the objects.






            let debts = [{amount: 10,debtor: "Mark",creditor: "John"},{amount: 20,debtor: "Mark",creditor: "John"},{amount: 10,debtor: "Mark",creditor: "Tom"}];

            let result = Object.values(debts.reduce((a,c) => {
            let key = `${c.debtor}~~${c.creditor}`;
            if(a[key]) a[key].amount += c.amount;
            else a[key] = Object.assign({},c);
            return a;
            }, {}));
            console.log(result);








            let debts = [{amount: 10,debtor: "Mark",creditor: "John"},{amount: 20,debtor: "Mark",creditor: "John"},{amount: 10,debtor: "Mark",creditor: "Tom"}];

            let result = Object.values(debts.reduce((a,c) => {
            let key = `${c.debtor}~~${c.creditor}`;
            if(a[key]) a[key].amount += c.amount;
            else a[key] = Object.assign({},c);
            return a;
            }, {}));
            console.log(result);





            let debts = [{amount: 10,debtor: "Mark",creditor: "John"},{amount: 20,debtor: "Mark",creditor: "John"},{amount: 10,debtor: "Mark",creditor: "Tom"}];

            let result = Object.values(debts.reduce((a,c) => {
            let key = `${c.debtor}~~${c.creditor}`;
            if(a[key]) a[key].amount += c.amount;
            else a[key] = Object.assign({},c);
            return a;
            }, {}));
            console.log(result);






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered yesterday









            Nikhil Aggarwal

            23.1k32647




            23.1k32647












            • Looks great, why do you used a[key] = Object.assign({},c) instead of a[key] = c?
              – SergioP
              yesterday










            • @SergioP - Objects are passed by reference and whenever a[key].amount += c.amount; the object is modified. I wanted to avoid overwriting the object in the array
              – Nikhil Aggarwal
              yesterday








            • 1




              Thanks for the explanation. :-)
              – SergioP
              yesterday




















            • Looks great, why do you used a[key] = Object.assign({},c) instead of a[key] = c?
              – SergioP
              yesterday










            • @SergioP - Objects are passed by reference and whenever a[key].amount += c.amount; the object is modified. I wanted to avoid overwriting the object in the array
              – Nikhil Aggarwal
              yesterday








            • 1




              Thanks for the explanation. :-)
              – SergioP
              yesterday


















            Looks great, why do you used a[key] = Object.assign({},c) instead of a[key] = c?
            – SergioP
            yesterday




            Looks great, why do you used a[key] = Object.assign({},c) instead of a[key] = c?
            – SergioP
            yesterday












            @SergioP - Objects are passed by reference and whenever a[key].amount += c.amount; the object is modified. I wanted to avoid overwriting the object in the array
            – Nikhil Aggarwal
            yesterday






            @SergioP - Objects are passed by reference and whenever a[key].amount += c.amount; the object is modified. I wanted to avoid overwriting the object in the array
            – Nikhil Aggarwal
            yesterday






            1




            1




            Thanks for the explanation. :-)
            – SergioP
            yesterday






            Thanks for the explanation. :-)
            – SergioP
            yesterday












            up vote
            1
            down vote













            Use the filter() function to iterate through the resulting list and check if the debtor-creditor pair already exist. If it exists, then updates the amount. Otherwise, add it as a new entry in the resulting list.






            const debts = [
            {
            amount: 10,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 20,
            debtor: "Mark",
            creditor: "John"
            },
            {
            amount: 10,
            debtor: "Mark",
            creditor: "Tom"
            }
            ];

            var result =
            debts.forEach((item) => {
            var existing = result.filter((resultItem, index) => {
            return resultItem.debtor === item.debtor && resultItem.creditor === item.creditor;
            });

            if (existing.length) {
            var existingIndex = result.indexOf(existing[0]);
            result[existingIndex].amount += item.amount;
            } else {
            result.push(item);
            }
            })

            console.log(result)








            share|improve this answer

























              up vote
              1
              down vote













              Use the filter() function to iterate through the resulting list and check if the debtor-creditor pair already exist. If it exists, then updates the amount. Otherwise, add it as a new entry in the resulting list.






              const debts = [
              {
              amount: 10,
              debtor: "Mark",
              creditor: "John"
              },
              {
              amount: 20,
              debtor: "Mark",
              creditor: "John"
              },
              {
              amount: 10,
              debtor: "Mark",
              creditor: "Tom"
              }
              ];

              var result =
              debts.forEach((item) => {
              var existing = result.filter((resultItem, index) => {
              return resultItem.debtor === item.debtor && resultItem.creditor === item.creditor;
              });

              if (existing.length) {
              var existingIndex = result.indexOf(existing[0]);
              result[existingIndex].amount += item.amount;
              } else {
              result.push(item);
              }
              })

              console.log(result)








              share|improve this answer























                up vote
                1
                down vote










                up vote
                1
                down vote









                Use the filter() function to iterate through the resulting list and check if the debtor-creditor pair already exist. If it exists, then updates the amount. Otherwise, add it as a new entry in the resulting list.






                const debts = [
                {
                amount: 10,
                debtor: "Mark",
                creditor: "John"
                },
                {
                amount: 20,
                debtor: "Mark",
                creditor: "John"
                },
                {
                amount: 10,
                debtor: "Mark",
                creditor: "Tom"
                }
                ];

                var result =
                debts.forEach((item) => {
                var existing = result.filter((resultItem, index) => {
                return resultItem.debtor === item.debtor && resultItem.creditor === item.creditor;
                });

                if (existing.length) {
                var existingIndex = result.indexOf(existing[0]);
                result[existingIndex].amount += item.amount;
                } else {
                result.push(item);
                }
                })

                console.log(result)








                share|improve this answer












                Use the filter() function to iterate through the resulting list and check if the debtor-creditor pair already exist. If it exists, then updates the amount. Otherwise, add it as a new entry in the resulting list.






                const debts = [
                {
                amount: 10,
                debtor: "Mark",
                creditor: "John"
                },
                {
                amount: 20,
                debtor: "Mark",
                creditor: "John"
                },
                {
                amount: 10,
                debtor: "Mark",
                creditor: "Tom"
                }
                ];

                var result =
                debts.forEach((item) => {
                var existing = result.filter((resultItem, index) => {
                return resultItem.debtor === item.debtor && resultItem.creditor === item.creditor;
                });

                if (existing.length) {
                var existingIndex = result.indexOf(existing[0]);
                result[existingIndex].amount += item.amount;
                } else {
                result.push(item);
                }
                })

                console.log(result)








                const debts = [
                {
                amount: 10,
                debtor: "Mark",
                creditor: "John"
                },
                {
                amount: 20,
                debtor: "Mark",
                creditor: "John"
                },
                {
                amount: 10,
                debtor: "Mark",
                creditor: "Tom"
                }
                ];

                var result =
                debts.forEach((item) => {
                var existing = result.filter((resultItem, index) => {
                return resultItem.debtor === item.debtor && resultItem.creditor === item.creditor;
                });

                if (existing.length) {
                var existingIndex = result.indexOf(existing[0]);
                result[existingIndex].amount += item.amount;
                } else {
                result.push(item);
                }
                })

                console.log(result)





                const debts = [
                {
                amount: 10,
                debtor: "Mark",
                creditor: "John"
                },
                {
                amount: 20,
                debtor: "Mark",
                creditor: "John"
                },
                {
                amount: 10,
                debtor: "Mark",
                creditor: "Tom"
                }
                ];

                var result =
                debts.forEach((item) => {
                var existing = result.filter((resultItem, index) => {
                return resultItem.debtor === item.debtor && resultItem.creditor === item.creditor;
                });

                if (existing.length) {
                var existingIndex = result.indexOf(existing[0]);
                result[existingIndex].amount += item.amount;
                } else {
                result.push(item);
                }
                })

                console.log(result)






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered yesterday









                Andreas

                1,224315




                1,224315






























                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53372012%2fjavascript-remove-duplicate-in-a-list-of-objects-merging-some-properties%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

                    Saint-Aignan (Tarn-et-Garonne)

                    Volksrepublik China

                    How to test boost logger output in unit testing?