如何根据id与previousSibling重新排序数组并生成新数组?
基于previousSibling的数组排序问题及解决方案
更新说明
以下是预期效果的基础示例:
下方是从服务器获取的当前数据格式:
[ { "id": "a2ae04b7-11b3-406f-ab14-3df57a92d01e", "title": "#", "previousSibling": "af8c3266-4cb0-46f4-ab13-30ba1b1baa3f", "children": [] }, { "id": "af8c3266-4cb0-46f4-ab13-30ba1b1baa3f", "title": "#", "children": [ { "id": "89cb6ed6-a0af-43ee-9c03-c907766e9804", "title": "#", "parent": "af8c3266-4cb0-46f4-ab13-30ba1b1baa3f", "previousSibling": "9b0b1d6f-b055-4d9d-af76-7f6345fcedd0", "children": [] }, { "id": "9b0b1d6f-b055-4d9d-af76-7f6345fcedd0", "title": "#", "parent": "af8c3266-4cb0-46f4-ab13-30ba1b1baa3f", "children": [] } ] }, { "id": "fa331d8b-8893-43ba-b2b1-a0824a959f00", "title": "#", "previousSibling": "a2ae04b7-11b3-406f-ab14-3df57a92d01e", "children": [] } ]
需求与问题
需要基于id和previousSibling属性对数组重新排序:排序逻辑为,若某元素id为X,下一个元素的previousSibling值应为X,以此类推。
目前可以自定义previousSibling值并提交至服务器,但刷新页面后数据位置并未改变,求解决方案。
解决方案
1. 验证服务器存储正确性
提交previousSibling后,重新调用API获取数据,核对返回的每个元素的previousSibling值是否与提交内容一致。若服务器未正确存储该字段,需先修复后端存储逻辑。
2. 前端实现排序逻辑
无论服务器返回顺序如何,前端可自行实现排序逻辑确保渲染顺序正确,代码如下:
function sortByPreviousSibling(items) { const itemMap = new Map(items.map(item => [item.id, item])); const sortedList = []; // 找到起始节点:无previousSibling或对应的节点不存在 let currentItem = items.find(item => !item.previousSibling || !itemMap.has(item.previousSibling)); while (currentItem) { sortedList.push(currentItem); // 按previousSibling匹配下一个节点 currentItem = items.find(item => item.previousSibling === currentItem.id); } // 处理孤立节点(如循环引用或无效previousSibling的节点) const remainingItems = items.filter(item => !sortedList.includes(item)); sortedList.push(...remainingItems); return sortedList; } // 使用示例 const serverData = [/* 服务器返回的原始数组 */]; const sortedData = sortByPreviousSibling(serverData); // 用sortedData进行页面渲染
3. 递归处理嵌套子元素排序
如果子元素也需要遵循相同排序规则,需递归处理每个元素的children数组:
function sortNestedItems(items) { const sortedParent = sortByPreviousSibling(items); return sortedParent.map(item => ({ ...item, children: item.children ? sortNestedItems(item.children) : [] })); } // 使用示例 const fullySortedData = sortNestedItems(serverData);
4. 排查常见异常
- 循环引用:避免出现A的
previousSibling是B、B的previousSibling是A的情况,提交数据时需做校验,或在排序函数中加入循环检测逻辑。 - 无效节点:若元素的
previousSibling对应的id不存在,需根据业务需求决定是作为起始节点还是追加到末尾。 - 服务器返回顺序依赖:不要假设服务器会按排序规则返回数据,始终在前端执行排序逻辑。
内容的提问来源于stack exchange,提问作者Julio Graffin
相关产品推荐
相关产品推荐

