// 完整测试新算法 const members = [{"id":"4661dd7b","name":"唐治明","birthYear":1960,"gender":"男","generation":"父亲","fatherId":"f24a95c7"},{"id":"d4498bfb","name":"舒邦莲","birthYear":1960,"gender":"女","generation":"父亲"},{"id":"f24a95c7","name":"唐有奎","birthYear":1900,"gender":"男","generation":"祖父"},{"id":"1be537aa","name":"唐治安","birthYear":1960,"gender":"男","generation":"父亲","fatherId":"f24a95c7"},{"id":"e6d9c5b3","name":"万华群","birthYear":1960,"gender":"女","generation":"父亲"},{"id":"4b78f55d","name":"唐治芳","birthYear":1960,"gender":"女","generation":"父亲","fatherId":"f24a95c7"},{"id":"a7bcc3b5","name":"邓能春","birthYear":1960,"gender":"男","generation":"父亲"}]; const map = {}; members.forEach(m => map[m.id] = m); const families = { '4661dd7b|d4498bfb': { fatherId: '4661dd7b', motherId: 'd4498bfb' }, '1be537aa|e6d9c5b3': { fatherId: '1be537aa', motherId: 'e6d9c5b3' }, 'a7bcc3b5|4b78f55d': { fatherId: 'a7bcc3b5', motherId: '4b78f55d' } }; const familyKeyOfChild = { '4661dd7b': 'f24a95c7|', '1be537aa': 'f24a95c7|', '4b78f55d': 'f24a95c7|' }; const prevOrderIndex = { 'f24a95c7': 0 }; const row = members; const memberSet = new Set(row.map(m => m.id)); // 1. 识别配偶关系 const spouseOf = {}; Object.keys(families).forEach(key => { const fam = families[key]; if (!fam || !fam.fatherId || !fam.motherId) return; if (memberSet.has(fam.fatherId) && memberSet.has(fam.motherId)) { spouseOf[fam.fatherId] = fam.motherId; spouseOf[fam.motherId] = fam.fatherId; } }); // 2. 按血缘分组 const siblingGroups = {}; row.forEach(m => { const key = familyKeyOfChild[m.id] || `solo:${m.id}`; if (!siblingGroups[key]) siblingGroups[key] = []; siblingGroups[key].push(m); }); console.log('兄弟姐妹分组:'); Object.keys(siblingGroups).forEach(key => { console.log(` ${key}: ${siblingGroups[key].map(m => m.name).join(', ')}`); }); // 3. 构建家庭单元 const familyUnits = []; const globalProcessed = new Set(); function compareByBirthName(a, b) { if (a.birthYear !== b.birthYear) return b.birthYear - a.birthYear; return a.name.localeCompare(b.name, 'zh-Hans-CN'); } Object.keys(siblingGroups).forEach(groupKey => { const siblings = siblingGroups[groupKey].slice().sort(compareByBirthName); const unitMembers = []; siblings.forEach(person => { if (globalProcessed.has(person.id)) return; globalProcessed.add(person.id); const spouseId = spouseOf[person.id]; if (spouseId && memberSet.has(spouseId)) { globalProcessed.add(spouseId); const spouse = map[spouseId]; if (person.gender === '男') { unitMembers.push(person, spouse); } else { unitMembers.push(spouse, person); } } else { unitMembers.push(person); } }); if (unitMembers.length > 0) { familyUnits.push({ groupKey, members: unitMembers }); } }); console.log('\n家庭单元:'); familyUnits.forEach((unit, i) => { const names = unit.members.map(m => m.name).join(' + '); console.log(` Unit ${i} (${unit.groupKey}): ${names}`); }); // 4. 计算权重并排序 function getUnitWeight(unit) { const key = unit.groupKey; if (key.startsWith('solo:')) { return { parentIdx: 9999, birthYear: unit.members[0].birthYear }; } const parts = key.split('|'); const fId = parts[0] || null; const mId = parts[1] || null; const indices = []; if (fId && prevOrderIndex[fId] !== undefined) indices.push(prevOrderIndex[fId]); if (mId && prevOrderIndex[mId] !== undefined) indices.push(prevOrderIndex[mId]); const parentIdx = indices.length > 0 ? Math.min(...indices) : 9999; const birthYear = Math.max(...unit.members.map(m => m.birthYear)); return { parentIdx, birthYear }; } familyUnits.sort((a, b) => { const wa = getUnitWeight(a); const wb = getUnitWeight(b); if (wa.parentIdx !== wb.parentIdx) return wa.parentIdx - wb.parentIdx; if (wa.birthYear !== wb.birthYear) return wb.birthYear - wa.birthYear; return 0; }); console.log('\n排序后的家庭单元:'); familyUnits.forEach((unit, i) => { const names = unit.members.map(m => m.name).join(' + '); const weight = getUnitWeight(unit); console.log(` ${i}. ${names} (parentIdx=${weight.parentIdx}, birthYear=${weight.birthYear})`); }); // 5. 展开为最终结果 const result = []; familyUnits.forEach(unit => result.push(...unit.members)); console.log('\n最终排序结果:'); console.log(result.map(m => m.name).join(', ')); console.log('\n期望结果:'); console.log('唐治安, 万华群, 唐治芳, 邓能春, 唐治明, 舒邦莲, 唐有奎'); console.log('\n说明: 唐治安、唐治芳、唐治明都是唐有奎的孩子,应该排在前面(parentIdx=0)'); console.log(' 舒邦莲、万华群、邓能春是外来配偶,紧贴在丈夫/妻子旁边'); console.log(' 唐有奎没有父母信息,排到最后(parentIdx=9999)');