Reputation: 13
I have this array, and I want to sum property (y
) of the array elements when x
matches certain criteria. For example, if "x" has the same string value between "/" and "?" as another object then add their "y" property together.
const data = [
{
"x": "/shop.html",
"y": 3
},
{
"x": "/",
"y": 2
},
{
"x": "/?test324",
"y": 1
},
{
"x": "/account.html",
"y": 1
},
{
"x": "/account.html?test1",
"y": 1
},
{
"x": "/shop.html?test543",
"y": 1
}
]
And it should be like this at the end
const expectedResult = [
{
"x": "/shop.html",
"y": 4
},
{
"x": "/",
"y": 3
},
{
"x": "/account.html",
"y": 2
},
]
So as you can see the 2nd array doesn't have the "?xxx" thing, they are all "merged" based on string value between last "/" and "?"
Tried to do something like this
let output = res.data.data.reduce(function (accumulator, cur) {
let x = cur.x,
found = accumulator.find(function (elem) {
elem.x = elem.x.split("?")[0];
return elem.x == x;
});
if (found) found.y += cur.y;
else accumulator.push(cur);
return accumulator;
}, []);
But duplicated values doesn't add themselves.
It returns me this
[
{
"x": "/shop.html",
"y": 3
},
{
"x": "/",
"y": 2
},
{
"x": "/",
"y": 1
},
{
"x": "/account.html",
"y": 1
},
{
"x": "/account.html",
"y": 1
},
{
"x": "/shop.html?test543",
"y": 1
}
]
Any idea?
Upvotes: 0
Views: 697
Reputation: 3691
The below may be one possible solution to achieve the desired objective.
Code Snippet
// a small helper method to convert key by leaving out the z-s in: '/xxxx?zzz'
const convertKey = x => (x.split('?')[0]);
// use reduce to iterate thru the array & obtain a result-object
// destructure to get 'x', 'y'
// if 'x' already present, add 'y'
// else create an object with 'x', 'y' props
// return the `Object.values` of the result-object
const transform = arr => (
Object.values(
arr.reduce(
(acc, {x, y}) => ({
...acc,
[convertKey(x)]: {
...(acc[convertKey(x)] || {x}),
y: (acc[convertKey(x)]?.y || 0) + y
}
}),
{}
)
)
);
const data = [
{
"x": "/shop.html",
"y": 3
},
{
"x": "/",
"y": 2
},
{
"x": "/?test324",
"y": 1
},
{
"x": "/account.html",
"y": 1
},
{
"x": "/account.html?test1",
"y": 1
},
{
"x": "/shop.html?test543",
"y": 1
}
];
console.log(transform(data));
Explanation
The above code-snippet has inline comments describing the steps. For further description, please post specific questions on comments below, if required.
Upvotes: 1