Untitled

mail@pastecode.io avatarunknown
plain_text
a month ago
7.1 kB
1
Indexable
Never
let data = []
];

// Must-have criteria
const mustHaveCriteria = {
    ageDifference: 5, // Maximum age difference allowed
    englishLevels: {
        low: [1, 2, 3, 4, 5], // English levels 1-5
        high: [6, 7, 8, 9, 10], // English levels 6-10
    },
    maxGroupSize: 6, // Maximum number of people in each group
    maxGenderCount: {
        man: 4, // Maximum number of men in each group
        woman: 4, // Maximum number of women in each group
        'non-binary': 4 // Maximum number of non-binary people in each group
    },
};

// Other properties for comparison
const column_param = [
    "countryOrigin",
    "gender",
    "relationship",
    "industryOfWork",
    "liveInLisbon",
    "englishLevel",
    "introverted",
    "calm",
    "selfmotivated",
    "creative",
    "amazingJob",
    "easyToConnect",
    "straightfoward",
    "attractivness",
    "family",
    "spirituality",
    "challenge",
    "humor",
    "nonConformity",
    "speakGroup",
    "speakDinner",
    "lonely",
    "outdoor",
    "drinking",
    "dancing",
    "drug",
    "sport",
    "attractive",
    "academicSuccess",
    "clothing",
    "spendingTime",
    "eatingfood",
    "planAction",
    "spending",
    "workout",
    "politicalyIncorrect",
    "politicalNews",
    "challengingDiscussions",
    "smartOrFunny",
    "earlyNight",
    "partyPicnic",
    "intellectualSporty",
    "idealNight",
    "socialClass",
    "orientation",
    "numberChildren",
    "child",
    "religion",
    "zodiac",
    "film",
    "stressed"
];

function randomSort(arr) {
    for (let i = arr.length - 1; i > 0; i--) {
        const randomIndex = Math.floor(Math.random() * (i + 1));
        [arr[i], arr[randomIndex]] = [arr[randomIndex], arr[i]];
    }
    return arr;
}

data = randomSort(data);
// Function to group people
function groupPeople() {
    const groups = [];
    // Iterate over each person in the data
    while (data.length > 0) {
        // Check if the person can be added to an existing group
        const person = data.shift();
        let maxMatchingScore = -Infinity;
        let targetGroupIndex = -1;
        let replaceIndex = -1;
        let replaceMember = null;

        for (let i = 0; i < groups.length; i++) {
            const group = groups[i];

            const groupSize = group.length;
            const personGender = person?.gender?.toLowerCase();
            const groupGenderCount = countGender(personGender, group);

            if (
                !isValidAgeDifference(person, group) ||
                !speakingSameLanguage(person, group)
            ) {
                continue;
            }

            if (groupSize === mustHaveCriteria.maxGroupSize ||
                groupGenderCount === mustHaveCriteria.maxGenderCount[personGender] ||
                (groupGenderCount === Math.floor(mustHaveCriteria.maxGroupSize / 2) && countValidMembersDifferentGenderInData(group, person) + groupSize >= mustHaveCriteria.maxGroupSize)
            ) {
                
            } else {
                const matchingScore = calculateGroupMatchingScore([person].concat(group));

                if (matchingScore > maxMatchingScore) {
                    maxMatchingScore = matchingScore;
                    targetGroupIndex = i;
                    replaceIndex = -1;
                    replaceMember = null;
                }
            }
        }

        if (targetGroupIndex !== -1) {
            if (replaceIndex !== -1) {
                data.push(replaceMember);
                groups[targetGroupIndex][replaceIndex] = person;
            } else {
                groups[targetGroupIndex].push(person);
            }
        } else {
            groups.push([person]);
        }
    }

    return groups;
}

// Function to count valid members in the data
function countValidMembersDifferentGenderInData(group, person) {

    return data.filter((member) => member?.gender !== person?.gender).length;
}

const isNumeric = (str) => {
    return !isNaN(str) && isFinite(str);
};

// Calculate the age difference between a person and the average age of a group
function isValidAgeDifference(person, group) {
    const birthYear = isNumeric(person?.year) ? parseInt(person?.year) : 0
    return !group.some((member) => {
        const memberBirthYear = isNumeric(member?.year) ? parseInt(member?.year) : 0;
        const ageDifference = Math.abs(birthYear - memberBirthYear);
        return ageDifference > mustHaveCriteria.ageDifference;
    });
}

// Check if the person's English level matches the group's requirement
function isValidEnglishLevel(person, group) {
    const englishLevels = mustHaveCriteria.englishLevels;
    const personEnglishLevel = parseInt(person?.englishLevel);

    if (group.length === 0) {
        return true;
    }

    if (group.some((p) => englishLevels.low.includes(parseInt(p?.englishLevel)))) {
        return englishLevels.low.includes(personEnglishLevel);
    } else {
        return englishLevels.high.includes(personEnglishLevel);
    }
}

function speakingSameLanguage(person, group) {
    if (group.length === 0) {
        return true;
    }
    return group.findIndex((p) => p?.speakDinner=== person?.speakDinner) > -1;
}

// Count the number of people with the specified gender in a group
function countGender(gender, group) {
    return group.filter((person) => person.gender?.toLowerCase() === gender?.toLowerCase()).length;
}

function calculateGroupMatchingScore(group) {
    const groupLength = group.length;
    if (groupLength === 1) {
        return column_param.length;
    }
    const totalMatchingCount = group.reduce((acc, person, i) => {
        const otherPeople = group.slice(i + 1);

        column_param.forEach((property) => {
            const matchingCount = otherPeople.filter((otherPerson) => person?.[property] === otherPerson?.[property])?.length || 0;
            acc += matchingCount;
        });

        return acc;
    }, 0);

    return totalMatchingCount / groupLength;
}


function findMemberToReplace(person, group) {
    let maxMatchingScore = calculateGroupMatchingScore(group);
    let targetIndex = -1;

    group.forEach((member, index) => {
        if (member?.gender === person?.gender) {
            const updatedGroup = [...group];
            updatedGroup[index] = person;
            const matchingScore = calculateGroupMatchingScore(updatedGroup);

            if (matchingScore > maxMatchingScore) {
                maxMatchingScore = matchingScore;
                targetIndex = index;
            }
        }
    });

    return targetIndex;
}

const getGroupUsers = (group) => {
    return group.map((person) => {
        return {
            "referenceValue": person?.idf || ""
        }
    })
}

// Example usage
let groups = groupPeople();

groups = groups.map((group, index) => {
    return JSON.stringify({
        "fields": {
            "usersList": {
                "arrayValue": {
                    "values": getGroupUsers(group)
                }
            },
            "Nom": {
                "stringValue": `table ${index}`
            }
        }
    })
});

groups;