// 测试新的配偶放置策略(左右分离) 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: '父亲' }, { id: '208fb133', name: '唐伟', birthYear: 1990, gender: '男', generation: '自己', fatherId: '4661dd7b', motherId: 'd4498bfb' }, { id: 'ab86880b', name: '唐永洪', birthYear: 1990, gender: '男', generation: '自己', fatherId: '4661dd7b', motherId: 'd4498bfb' }, { id: 'de8e2fc8', name: '唐雪', birthYear: 1990, gender: '女', generation: '自己', fatherId: '1be537aa', motherId: 'e6d9c5b3' }, { id: '08a22bcd', name: '唐波', birthYear: 1990, gender: '男', generation: '自己', fatherId: '1be537aa', motherId: 'e6d9c5b3' }, { id: '1ebd23c6', name: '邓静', birthYear: 1990, gender: '女', generation: '自己', fatherId: 'a7bcc3b5', motherId: '4b78f55d' }, { id: '4c3f6e87', name: '邓正悦', birthYear: 1990, gender: '女', generation: '自己', fatherId: 'a7bcc3b5', motherId: '4b78f55d' }, { id: 'a74c5ba0', name: '张红', birthYear: 1990, gender: '女', generation: '自己' }, { id: '95672071', name: '郭思琪', birthYear: 1990, gender: '女', generation: '自己' }, { id: '6fb43781', name: '彭先生', birthYear: 1990, gender: '男', generation: '自己' }, { id: 'a1fa7080', name: '唐世宁', birthYear: 2020, gender: '女', generation: '子女', fatherId: 'ab86880b', motherId: '95672071' }, { id: '74ab3d7a', name: '唐瑾瑜', birthYear: 2020, gender: '女', generation: '子女', fatherId: '08a22bcd', motherId: 'a74c5ba0' }, { id: '6365ca6a', name: '唐世严', birthYear: 2020, gender: '男', generation: '子女', fatherId: '08a22bcd', motherId: 'a74c5ba0' }, { id: '4736c2bb', name: '彭瑾瑜', birthYear: 2020, gender: '女', generation: '子女', fatherId: '6fb43781', motherId: '1ebd23c6' } ]; const map = {}; members.forEach(m => (map[m.id] = m)); const families = {}; const familyKeyOfChild = {}; members.forEach(child => { const fatherId = child.fatherId && map[child.fatherId] ? child.fatherId : ''; const motherId = child.motherId && map[child.motherId] ? child.motherId : ''; if (!fatherId && !motherId) return; const key = `${fatherId}|${motherId}`; familyKeyOfChild[child.id] = key; if (!families[key]) families[key] = { fatherId: fatherId || null, motherId: motherId || null, children: [] }; families[key].children.push(child.id); }); const gen2 = members.filter(m => m.generation === '自己'); const memberSet = new Set(gen2.map(m => m.id)); 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; } }); const bloodMembers = []; const spouseMembers = new Set(); gen2.forEach(m => { const hasParents = (m.fatherId && map[m.fatherId]) || (m.motherId && map[m.motherId]); const isSpouseOnly = !hasParents && spouseOf[m.id]; if (isSpouseOnly) { spouseMembers.add(m.id); } else { bloodMembers.push(m); } }); const siblingGroups = {}; bloodMembers.forEach(m => { const key = familyKeyOfChild[m.id] || `solo:${m.id}`; if (!siblingGroups[key]) siblingGroups[key] = []; siblingGroups[key].push(m); }); function compareByBirthName(a, b) { if (a.birthYear !== b.birthYear) return b.birthYear - a.birthYear; return a.name.localeCompare(b.name, 'zh-Hans-CN'); } const familyUnits = []; const globalProcessed = new Set(); Object.keys(siblingGroups).forEach(groupKey => { const siblings = siblingGroups[groupKey].slice().sort(compareByBirthName); const leftSpouses = []; const coreMembers = []; const rightSpouses = []; siblings.forEach(person => { if (globalProcessed.has(person.id)) return; globalProcessed.add(person.id); coreMembers.push(person); const spouseId = spouseOf[person.id]; if (spouseId && memberSet.has(spouseId)) { globalProcessed.add(spouseId); const spouse = map[spouseId]; if (person.gender === '男') { rightSpouses.push(spouse); } else { leftSpouses.push(spouse); } } }); const unitMembers = [...leftSpouses, ...coreMembers, ...rightSpouses]; if (unitMembers.length > 0) { familyUnits.push({ groupKey, members: unitMembers }); } }); console.log('=== 新策略:家庭单元构建结果 ==='); familyUnits.forEach((unit, idx) => { const names = unit.members.map(m => { const isSpouse = spouseMembers.has(m.id); return isSpouse ? `[${m.name}]` : m.name; }); console.log(`单元 ${idx + 1} (${unit.groupKey}):`); console.log(` ${names.join(' - ')}`); }); // 排序(使用简化的父母位置) const gen1 = members.filter(m => m.generation === '父亲'); const prevOrderIndex = {}; gen1.forEach((m, idx) => { prevOrderIndex[m.id] = idx; }); 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 bloodMembersInUnit = unit.members.filter(m => !spouseMembers.has(m.id)); const birthYear = bloodMembersInUnit.length > 0 ? Math.max(...bloodMembersInUnit.map(m => m.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=== 最终排序结果(第三代)==='); const result = []; familyUnits.forEach(unit => { result.push(...unit.members); }); console.log(result.map(m => m.name).join(' → ')); console.log('\n=== 连接验证 ==='); console.log('唐治明+舒邦莲 的孩子: 唐伟, 唐永洪'); console.log(' 位置:', result.findIndex(m => m.name === '唐伟'), result.findIndex(m => m.name === '唐永洪')); console.log('唐治安+万华群 的孩子: 唐波, 唐雪'); console.log(' 位置:', result.findIndex(m => m.name === '唐波'), result.findIndex(m => m.name === '唐雪')); console.log('唐治芳+邓能春 的孩子: 邓静, 邓正悦'); console.log(' 位置:', result.findIndex(m => m.name === '邓静'), result.findIndex(m => m.name === '邓正悦'));