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
javascript arrays lodash ramda.js
add a comment |
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
javascript arrays lodash ramda.js
add a comment |
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
javascript arrays lodash ramda.js
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
javascript arrays lodash ramda.js
asked yesterday
SergioP
304
304
add a comment |
add a comment |
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:
- Group debtors and creditors together
- For each debtor/creditor group, merge the amount
- 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"
}
]
Slightly cleaner, perhaps, would bemap(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 callgroupKey
. 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 convertmap(reduce(mergeAmount, {amount: 0}))
tomap(reduce(mergeAmount, {}))
because if the key doesn't exist in bothmergeWithKey
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
|
show 1 more comment
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);
Looks great, why do you useda[key] = Object.assign({},c)
instead ofa[key] = c
?
– SergioP
yesterday
@SergioP - Objects are passed by reference and whenevera[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
add a comment |
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)
add a comment |
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:
- Group debtors and creditors together
- For each debtor/creditor group, merge the amount
- 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"
}
]
Slightly cleaner, perhaps, would bemap(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 callgroupKey
. 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 convertmap(reduce(mergeAmount, {amount: 0}))
tomap(reduce(mergeAmount, {}))
because if the key doesn't exist in bothmergeWithKey
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
|
show 1 more comment
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:
- Group debtors and creditors together
- For each debtor/creditor group, merge the amount
- 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"
}
]
Slightly cleaner, perhaps, would bemap(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 callgroupKey
. 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 convertmap(reduce(mergeAmount, {amount: 0}))
tomap(reduce(mergeAmount, {}))
because if the key doesn't exist in bothmergeWithKey
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
|
show 1 more comment
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:
- Group debtors and creditors together
- For each debtor/creditor group, merge the amount
- 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"
}
]
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:
- Group debtors and creditors together
- For each debtor/creditor group, merge the amount
- 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>
edited yesterday
answered yesterday
customcommander
555213
555213
Slightly cleaner, perhaps, would bemap(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 callgroupKey
. 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 convertmap(reduce(mergeAmount, {amount: 0}))
tomap(reduce(mergeAmount, {}))
because if the key doesn't exist in bothmergeWithKey
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
|
show 1 more comment
Slightly cleaner, perhaps, would bemap(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 callgroupKey
. 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 convertmap(reduce(mergeAmount, {amount: 0}))
tomap(reduce(mergeAmount, {}))
because if the key doesn't exist in bothmergeWithKey
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
|
show 1 more comment
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);
Looks great, why do you useda[key] = Object.assign({},c)
instead ofa[key] = c
?
– SergioP
yesterday
@SergioP - Objects are passed by reference and whenevera[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
add a comment |
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);
Looks great, why do you useda[key] = Object.assign({},c)
instead ofa[key] = c
?
– SergioP
yesterday
@SergioP - Objects are passed by reference and whenevera[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
add a comment |
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);
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);
answered yesterday
Nikhil Aggarwal
23.1k32647
23.1k32647
Looks great, why do you useda[key] = Object.assign({},c)
instead ofa[key] = c
?
– SergioP
yesterday
@SergioP - Objects are passed by reference and whenevera[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
add a comment |
Looks great, why do you useda[key] = Object.assign({},c)
instead ofa[key] = c
?
– SergioP
yesterday
@SergioP - Objects are passed by reference and whenevera[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
add a comment |
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)
add a comment |
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)
add a comment |
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)
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)
answered yesterday
Andreas
1,224315
1,224315
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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