Files
2026-06-22 22:59:01 +02:00

86 lines
2.3 KiB
TypeScript

import {
BigFiveDomain,
IpipNeoItem,
ipipNeo120Items,
ipipNeo300Items,
} from '@/questionairies/bigfive/neo-data';
const reverseItems = new Set([
2, 4, 6, 8, 10, 12, 16, 18, 19, 20, 22, 24, 26, 28, 29, 30, 32, 34,
36, 38, 39, 44, 46, 48, 49,
]);
const dimensions = {
extraversion: [1, 6, 11, 16, 21, 26, 31, 36, 41, 46],
agreeableness: [2, 7, 12, 17, 22, 27, 32, 37, 42, 47],
conscientiousness: [3, 8, 13, 18, 23, 28, 33, 38, 43, 48],
emotionalStability: [4, 9, 14, 19, 24, 29, 34, 39, 44, 49],
openness: [5, 10, 15, 20, 25, 30, 35, 40, 45, 50],
};
export function calculateBigFiveResults(answers: string[]) {
const scoreItem = (questionId: number) => {
const raw = Number(answers[questionId - 1] || 0);
if (!raw) return 0;
return reverseItems.has(questionId) ? 6 - raw : raw;
};
return Object.fromEntries(
Object.entries(dimensions).map(([key, items]) => {
const score = items.reduce((sum, item) => sum + scoreItem(item), 0);
return [
key,
{
score,
average: score / items.length,
},
];
}),
);
}
export const ipipNeoItemsByVersion = {
120: ipipNeo120Items,
300: ipipNeo300Items,
} as const;
export function calculateIpipNeoResults(
answers: string[],
items: IpipNeoItem[],
) {
const domainTotals = new Map<BigFiveDomain, { score: number; count: number }>();
const facetTotals = new Map<string, { score: number; count: number }>();
items.forEach((item, index) => {
const raw = Number(answers[index] || 0);
const score = raw ? (item.reverse ? 6 - raw : raw) : 0;
const domain = domainTotals.get(item.domain) || { score: 0, count: 0 };
domain.score += score;
domain.count += 1;
domainTotals.set(item.domain, domain);
const facet = facetTotals.get(item.facet) || { score: 0, count: 0 };
facet.score += score;
facet.count += 1;
facetTotals.set(item.facet, facet);
});
const toResults = (totals: Map<string, { score: number; count: number }>) =>
Object.fromEntries(
[...totals.entries()].map(([key, value]) => [
key,
{
score: value.score,
average: value.count ? value.score / value.count : 0,
itemCount: value.count,
},
]),
);
return {
domains: toResults(domainTotals),
facets: toResults(facetTotals),
};
}