const members = [{"id":"4661dd7b-f3b9-42d1-bf00-b14899e2a92e","name":"唐治明","birthYear":1960,"gender":"男","generation":"父亲","fatherId":"f24a95c7-fa68-4f56-b0ed-e1f7fb2c91e1"},{"id":"d4498bfb-c0ce-4218-bc8f-3f0cc0cf6984","name":"舒邦莲","birthYear":1960,"gender":"女","generation":"父亲"},{"id":"f24a95c7-fa68-4f56-b0ed-e1f7fb2c91e1","name":"唐有奎","birthYear":1900,"gender":"男","generation":"祖父"},{"id":"1be537aa-88cb-4b82-8c09-e18e05922499","name":"唐治安","birthYear":1960,"gender":"男","generation":"父亲","fatherId":"f24a95c7-fa68-4f56-b0ed-e1f7fb2c91e1"},{"id":"e6d9c5b3-6397-4d88-878b-e22e5c9f512b","name":"万华群","birthYear":1960,"gender":"女","generation":"父亲"},{"name":"唐治芳","birthYear":1960,"gender":"女","generation":"父亲","fatherId":"f24a95c7-fa68-4f56-b0ed-e1f7fb2c91e1","id":"4b78f55d-34b0-4407-a672-3d6b3e826f0f"},{"name":"邓能春","birthYear":1960,"gender":"男","generation":"父亲","id":"a7bcc3b5-c4fc-4fca-8bd4-44cf6078d678"},{"id":"208fb133-6a0b-4540-a1ff-ad8ce154c33f","name":"唐伟","birthYear":1990,"gender":"男","generation":"自己","fatherId":"4661dd7b-f3b9-42d1-bf00-b14899e2a92e","motherId":"d4498bfb-c0ce-4218-bc8f-3f0cc0cf6984"},{"name":"唐永洪","birthYear":1990,"gender":"男","generation":"自己","fatherId":"4661dd7b-f3b9-42d1-bf00-b14899e2a92e","motherId":"d4498bfb-c0ce-4218-bc8f-3f0cc0cf6984","id":"ab86880b-502c-4249-9ce4-ff3327c3fd1b"},{"id":"de8e2fc8-2a1e-4dc1-b010-cd29b9312105","name":"唐雪","birthYear":1990,"gender":"女","generation":"自己","fatherId":"1be537aa-88cb-4b82-8c09-e18e05922499","motherId":"e6d9c5b3-6397-4d88-878b-e22e5c9f512b"},{"name":"唐波","birthYear":1990,"gender":"男","generation":"自己","fatherId":"1be537aa-88cb-4b82-8c09-e18e05922499","motherId":"e6d9c5b3-6397-4d88-878b-e22e5c9f512b","id":"08a22bcd-5af6-4589-8739-9ea796c41a01"},{"name":"邓静","birthYear":1990,"gender":"女","generation":"自己","fatherId":"a7bcc3b5-c4fc-4fca-8bd4-44cf6078d678","motherId":"4b78f55d-34b0-4407-a672-3d6b3e826f0f","id":"1ebd23c6-dadf-4cec-98fe-5bff971bc591"},{"id":"4c3f6e87-8756-48de-9141-5881778974ce","name":"邓正悦","birthYear":1990,"gender":"女","generation":"自己","fatherId":"a7bcc3b5-c4fc-4fca-8bd4-44cf6078d678","motherId":"4b78f55d-34b0-4407-a672-3d6b3e826f0f"},{"name":"张红","birthYear":1990,"gender":"女","generation":"自己","id":"a74c5ba0-5fe1-4862-a651-f81b641deb72"},{"name":"郭思琪","birthYear":1990,"gender":"女","generation":"自己","id":"95672071-9f60-4728-9209-00a24a01fb3a"},{"id":"a1fa7080-3e49-49bb-b2d7-ec94e005369f","name":"唐世宁","birthYear":2020,"gender":"女","generation":"子女","fatherId":"ab86880b-502c-4249-9ce4-ff3327c3fd1b","motherId":"95672071-9f60-4728-9209-00a24a01fb3a"},{"id":"74ab3d7a-3dad-4279-aecb-13e7ef12c0ff","name":"唐瑾瑜","birthYear":2020,"gender":"女","generation":"子女","fatherId":"08a22bcd-5af6-4589-8739-9ea796c41a01","motherId":"a74c5ba0-5fe1-4862-a651-f81b641deb72"},{"id":"6365ca6a-f31f-4b7a-b233-bc5a101f7025","name":"唐世严","birthYear":2020,"gender":"男","generation":"子女","fatherId":"08a22bcd-5af6-4589-8739-9ea796c41a01","motherId":"a74c5ba0-5fe1-4862-a651-f81b641deb72"}]; const GEN_ORDER = ['鼻祖','远祖','太祖','烈祖','天祖','高祖','曾祖','祖父','父亲','自己','子女','孙辈','曾孙','玄孙','来孙','晜孙','仍孙','云孙','耳孙']; const map = {}; members.forEach(m => map[m.id] = m); const childrenOf = {}; members.forEach(m => { if (m.fatherId && map[m.fatherId]) (childrenOf[m.fatherId] = childrenOf[m.fatherId] || []).push(m.id); if (m.motherId && map[m.motherId]) (childrenOf[m.motherId] = childrenOf[m.motherId] || []).push(m.id); }); Object.keys(childrenOf).forEach(pid => { childrenOf[pid] = [...new Set(childrenOf[pid])]; }); const rankOf = {}; members.forEach(m => { if (m.generation) { const idx = GEN_ORDER.indexOf(m.generation); rankOf[m.id] = (idx >= 0 ? idx : 9) * 1000; } }); const bfsQueue = Object.keys(rankOf); const visitedBFS = new Set(bfsQueue); let qi = 0; while (qi < bfsQueue.length) { const pid = bfsQueue[qi++]; (childrenOf[pid] || []).forEach(cid => { const needed = Math.max( map[cid].fatherId && rankOf[map[cid].fatherId] !== undefined ? rankOf[map[cid].fatherId] + 1000 : 0, map[cid].motherId && rankOf[map[cid].motherId] !== undefined ? rankOf[map[cid].motherId] + 1000 : 0 ); if (rankOf[cid] === undefined || needed > rankOf[cid]) rankOf[cid] = needed; if (!visitedBFS.has(cid)) { visitedBFS.add(cid); bfsQueue.push(cid); } }); } members.forEach(m => { if (rankOf[m.id] === undefined) rankOf[m.id] = 9 * 1000; }); const uniqueRanks = [...new Set(Object.values(rankOf))].sort((a, b) => a - b); const rankToRow = {}; uniqueRanks.forEach((r, i) => { rankToRow[r] = i; }); const rowOf = {}; members.forEach(m => { rowOf[m.id] = rankToRow[rankOf[m.id]]; }); 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 familyOrderList = Object.keys(families) .map(key => { const fam = families[key]; const fatherYear = fam.fatherId ? map[fam.fatherId].birthYear : -Infinity; const motherYear = fam.motherId ? map[fam.motherId].birthYear : -Infinity; return { key, orderYear: Math.max(fatherYear, motherYear) }; }) .sort((a, b) => b.orderYear - a.orderYear || a.key.localeCompare(b.key)); const familyOrderIndex = {}; familyOrderList.forEach((item, idx) => { familyOrderIndex[item.key] = idx; }); const parentFamilyIndices = {}; Object.keys(families).forEach(key => { const fam = families[key]; const idx = familyOrderIndex[key]; if (fam.fatherId) (parentFamilyIndices[fam.fatherId] = parentFamilyIndices[fam.fatherId] || []).push(idx); if (fam.motherId) (parentFamilyIndices[fam.motherId] = parentFamilyIndices[fam.motherId] || []).push(idx); }); const parentPrimaryFamilyKey = {}; Object.keys(parentFamilyIndices).forEach(pid => { const indices = parentFamilyIndices[pid]; const minIdx = Math.min(...indices); parentPrimaryFamilyKey[pid] = familyOrderList[minIdx] ? familyOrderList[minIdx].key : null; }); function compareByBirthName(a, b) { if (a.birthYear !== b.birthYear) return b.birthYear - a.birthYear; return a.name.localeCompare(b.name, 'zh-Hans-CN'); } function sortRowWithParentOrder(row, prevOrderIndex) { const memberSet = new Set(row.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 parentGroups = {}; row.forEach(m => { const key = familyKeyOfChild[m.id] || `solo:${m.id}`; if (!parentGroups[key]) parentGroups[key] = []; parentGroups[key].push(m); }); // 计算每个父母组的排序索引 function getParentGroupIndex(key) { if (key.startsWith('solo:')) return null; 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]); return indices.length > 0 ? Math.min(...indices) : null; } // 对父母组排序 const sortedGroupKeys = Object.keys(parentGroups).sort((a, b) => { const aIdx = getParentGroupIndex(a); const bIdx = getParentGroupIndex(b); if (aIdx !== null && bIdx !== null && aIdx !== bIdx) return aIdx - bIdx; if (aIdx !== null && bIdx === null) return -1; if (aIdx === null && bIdx !== null) return 1; return a.localeCompare(b); }); // 展开每个父母组,先放兄弟姐妹,再放他们的配偶 const result = []; const processed = new Set(); sortedGroupKeys.forEach(groupKey => { const groupMembers = parentGroups[groupKey].slice().sort(compareByBirthName); const spousesToAdd = []; // 先添加所有兄弟姐妹 groupMembers.forEach(m => { if (processed.has(m.id)) return; result.push(m); processed.add(m.id); // 记录需要添加的配偶(如果配偶不在当前组) const spouseId = spouseOf[m.id]; if (spouseId && memberSet.has(spouseId) && !processed.has(spouseId)) { const spouseKey = familyKeyOfChild[spouseId] || `solo:${spouseId}`; if (spouseKey !== groupKey) { spousesToAdd.push(map[spouseId]); } } }); // 然后添加配偶 spousesToAdd.forEach(spouse => { if (!processed.has(spouse.id)) { result.push(spouse); processed.add(spouse.id); } }); }); return result; } function sortTopRow(row) { const sorted = row.slice().sort((a, b) => { const aKey = parentPrimaryFamilyKey[a.id]; const bKey = parentPrimaryFamilyKey[b.id]; if (aKey && bKey && aKey === bKey) { const fam = families[aKey]; if (fam && fam.fatherId === a.id && fam.motherId === b.id) return -1; if (fam && fam.motherId === a.id && fam.fatherId === b.id) return 1; } return compareByBirthName(a, b); }); return sorted; } const maxRow = Math.max(...Object.values(rowOf)); const gens = []; let prevOrderIndex = {}; for (let g = 0; g <= maxRow; g++) { const rowMembers = members.filter(m => rowOf[m.id] === g); const ordered = g === 0 ? sortTopRow(rowMembers) : sortRowWithParentOrder(rowMembers, prevOrderIndex); gens.push(ordered); prevOrderIndex = {}; ordered.forEach((m, idx) => { prevOrderIndex[m.id] = idx; }); console.log(`第${g}行排序结果: ${ordered.map(m => m.name).join(', ')}`); }