Reputation: 305
I have an array of object which have reference to its collection
const data = [{
id: 1,
name: 'A',
referer_id: null,
point: 4
},
{
id: 2,
name: 'B',
referer_id: 1,
point: 100
},
{
id: 3,
name: 'C',
referer_id: null,
point: 4
},
{
id: 4,
name: 'D',
referer_id: 1,
point: 2
},
{
id: 5,
name: 'E',
referer_id: null,
point: 4
},
{
id: 6,
name: 'F',
referer_id: null,
point: 4
},
{
id: 7,
name: 'G',
referer_id: 2,
point: 4
},
];
the referer id will refer to the id. And I have another array of number used to calculate the point
const pointsByLevel = [0.5, 0.3, 0.2]; // this would be dynamic from database
as of now, I can get the sum of all total like this
function getPoint(user_id) {
const mainUserPoint = data.find((u) => u.id === user_id).point;
let sum = 0;
for (let subdep of data.filter((d) => d.referer_id === user_id)) {
sum += getPoint(subdep.id);
}
return mainUserPoint + sum;
}
but the real challenge is the first level should return the point only but afterward the point will be multiplied to pointsByLevel
based on the index
so the output will be like this
console.log(getPoint(1));
/**
A - 4
B D - [100 * 0.5], [2 * 0.5]
G - [4 * 0.3]
**/
// 4 + 50 + 1 + 1.2 = 56.2
So the end result I'm gonna get 56.2
What is the most efficient way to do this
Upvotes: 0
Views: 38
Reputation: 11740
You'll have to keep track of how many levels deep you are as an additional argument to getPoint
. Set the default to 0, and the increment it each time you recurse. You can then find the corresponding points by level for it. (I inserted a 1.0 coefficient for level 0). I also added a comment to show the partial results at each level.
const data = [
{ id: 1, name: 'A', referer_id: null, point: 4 },
{ id: 2, name: 'B', referer_id: 1, point: 100 },
{ id: 3, name: 'C', referer_id: null, point: 4 },
{ id: 4, name: 'D', referer_id: 1, point: 2 },
{ id: 5, name: 'E', referer_id: null, point: 4 },
{ id: 6, name: 'F', referer_id: null, point: 4 },
{ id: 7, name: 'G', referer_id: 2, point: 4 }
];
const pointsByLevel = [1, 0.5, 0.3, 0.2]; // NOTE: I added a 1.0 for level 0
function getPoint(user_id, level = 0) {
const user = data.find((u) => u.id === user_id);
const mainUserPoint = user.point;
let sum = 0;
for (let subdep of data.filter((d) => d.referer_id === user_id)) {
let val = getPoint(subdep.id, level + 1);
sum += val;
}
let result = (mainUserPoint * pointsByLevel[level]) + sum;
console.log(`getPoint for ${user_id} "${user.name}" is ${level} levels deep and has the value ${result}`)
return result;
}
console.log(getPoint(1));
Upvotes: 1