Untitled
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;