Home > front end >  Get largest int from object inside of array that's under a limit
Get largest int from object inside of array that's under a limit

Time:07-05

I'm currently building a Discord.js bot were I wanna give role rewards depending on what level you reach.

This is my main part of the code to figure out what role to give, which works perfectly when your role rewards only have a 1 level difference (so from 1 to 2), but if I go from level 4 to 5 it doesn't know what to remove and just crashes because prevLvl is undefined.

When you reach a certain milestone it needs to give a new role and remove the previous one.

memberData.level = 4;

levelUpRoles = [ //These ones get pushed in array by user
    {role: 'id1', level: 1},
    {role: 'id2', level: 2},
    {role: 'id3', level: 5},
    {role: 'id4', level: 20},
    {role: 'id5', level: 10},
]

let newLvl = levelUpRoles.find(object => object.level === memberData.level);
let prevLvl = levelUpRoles.find(object => object.level === memberData.level - 1);

if (newLvl) {
    target.roles.add(newLvl.role).catch(console.error);

    target.roles.remove(prevLvl.role).catch(console.error);
}

This is what I've so far been able to come up with:

I changed the prevLvl to:

let prevLvl = levelUpRoles.filter(object => object.level < memberData.level).sort(function (a, b) {return a.level - b.level}).slice(0,-1).slice(-1);
let newLvl = levelUpRoles.find(object => object.level === memberData.level);
if (newLvl) {
    console.log(newLvl);
    target.roles.add(newLvl.role).catch(console.error);
    console.log(prevLvl);
    if (prevLvl) {
        target.roles.remove(prevLvl.role).catch(console.error);
    }
}

It first filters all roles that are under my level, then sorts all roles in order from level, then it removes my current role, then it removes all roles except the highest.

CodePudding user response:

After some tinkering with the edited part of my post I've finally managed to do it!

let prevLvl = levelUpRoles.filter(object => object.level <= memberData.level).sort(function (a, b) {return a.level - b.level}).slice(0,-1).slice(-1);
                    let newLvl = levelUpRoles.find(object => object.level === memberData.level);
                    if (newLvl) {
                        target.roles.add(newLvl.role).catch(console.error);
                        if (prevLvl[0]) {
                            target.roles.remove(prevLvl[0].role).catch(console.error);
                        }
                    }

This is what I came up with... First filter only the roles by level that are smaller or same as my level. Then I sort the array from small to big, then I cut everything except for the second highest which will be my previous reward.

Thanks to everyone that helped and led me in the right direction!

CodePudding user response:

Assuming levelUpRoles will consistently be in ascending order, you can check for the index of the lowest level value above memberData.level using the > operator.

Then, from that index, find the new level and previous level and do the necessary operations.

levelUpRoles = [
    {role: 'id1', level: '1'},
    {role: 'id2', level: '2'},
    {role: 'id3', level: '5'},
]

let nextIndex = levelUpRoles.findIndex(object => object.level > memberData.level);
if (nextIndex) {
    nextIndex > 0 || nextIndex = levelUpRoles.length; // If there is no next level

    const newLvl = levelUpRoles[nextIndex-1];
    target.roles.add(newLvl.role).catch(console.error);

    if (nextIndex > 1) { // If there exists a previous level
        const prevLvl = levelUpRoles[nextIndex-2];
        target.roles.remove(prevLvl.role).catch(console.error);
    }
}
  • Related