对象数组元素位置调整:指定元素分组并同步sort值
分组元素的数组位置调整实现
原数组与现有逻辑
原数组定义:
const links = [ { link: "google", sort: 0 }, { link: "facebook", sort: 1 }, { link: "ios", sort: 2 }, { link: "android", sort: 3 }, { link: "twitter", sort: 4 }, ]
此前已实现单元素位置调整逻辑:
const linkName = "twitter"; const sort = 1; const currentIndex = links.findIndex((e) => e.link == linkName); links.splice(sort, 0, links.splice(currentIndex, 1)[0]); links.map((e, i) => { e.sort = i; }); /* 修改后的数组: [ { link: 'google', sort: 0 }, { link: 'twitter', sort: 1 }, { link: 'facebook', sort: 2 }, { link: 'ios', sort: 3 }, { link: 'android', sort: 4 } ] */
新需求说明
需将"ios"和"android"设为一组,二者sort值始终保持相同,调整后目标数组如下:
[ { link: "google", sort: 0 }, { link: "facebook", sort: 1 }, { link: "ios", sort: 2 }, { link: "android", sort: 2 }, { link: "twitter", sort: 3 }, ]
同时需满足以下场景:
- 将"ios"或"android"移至索引0时,数组应为:
[ { link: "ios", sort: 0 }, { link: "android", sort: 0 }, { link: "google", sort: 1 }, { link: "facebook", sort: 2 }, { link: "twitter", sort: 3 }, ]
- 将该组移至索引1时,数组应为:
[ { link: "google", sort: 0 }, { link: "ios", sort: 1 }, { link: "android", sort: 1 }, { link: "facebook", sort: 2 }, { link: "twitter", sort: 3 }, ]
实现逻辑
通过以下步骤实现分组元素的位置调整:
- 定义分组配置,标记哪些元素属于同一组
- 处理移动请求时,先提取整个分组的元素(若目标元素在分组内)
- 从原数组中移除分组元素(注意从大索引开始删除,避免索引偏移)
- 将分组插入目标位置
- 重新计算所有元素的
sort值,确保分组内元素sort相同
具体代码实现:
// 定义分组配置:key为组内任意元素标识,value为组内所有元素集合 const groupConfig = { ios: ['ios', 'android'], android: ['ios', 'android'] }; // 调整位置的核心函数 function adjustLinkPosition(targetLink, targetIndex) { let elementsToMove; let originalIndices = []; // 判断目标元素是否属于分组 const targetGroup = groupConfig[targetLink]; if (targetGroup) { // 提取分组内所有元素,并记录它们在原数组的索引 elementsToMove = links.filter(item => targetGroup.includes(item.link)); originalIndices = elementsToMove.map(item => links.indexOf(item)); // 保持分组内元素在原数组的顺序(ios在前,android在后) elementsToMove.sort((a, b) => links.indexOf(a) - links.indexOf(b)); // 从大索引开始删除分组元素,防止索引偏移 originalIndices.sort((a, b) => b - a).forEach(idx => links.splice(idx, 1)); } else { // 单元素移动逻辑,沿用原有实现 const currentIndex = links.findIndex(e => e.link === targetLink); elementsToMove = [links.splice(currentIndex, 1)[0]]; } // 将元素插入目标位置 links.splice(targetIndex, 0, ...elementsToMove); // 重新计算sort值 let currentSort = 0; let i = 0; while (i < links.length) { const currentItem = links[i]; const itemGroup = groupConfig[currentItem.link]; if (itemGroup) { // 分组内元素设置相同sort值 const groupSize = itemGroup.filter(g => links.some(l => l.link === g)).length; for (let j = 0; j < groupSize; j++) { links[i + j].sort = currentSort; } i += groupSize; currentSort++; } else { currentItem.sort = currentSort; i++; currentSort++; } } }
测试场景验证
场景1:将ios移至索引0
adjustLinkPosition('ios', 0); console.log(links); // 输出结果: // [ // { link: "ios", sort: 0 }, // { link: "android", sort: 0 }, // { link: "google", sort: 1 }, // { link: "facebook", sort: 2 }, // { link: "twitter", sort: 3 }, // ]
场景2:将android移至索引1
// 先恢复原数组 const links = [ { link: "google", sort: 0 }, { link: "facebook", sort: 1 }, { link: "ios", sort: 2 }, { link: "android", sort: 3 }, { link: "twitter", sort: 4 }, ]; adjustLinkPosition('android', 1); console.log(links); // 输出结果: // [ // { link: "google", sort: 0 }, // { link: "ios", sort: 1 }, // { link: "android", sort: 1 }, // { link: "facebook", sort: 2 }, // { link: "twitter", sort: 3 }, // ]
场景3:单元素移动测试(将twitter移至索引2)
// 恢复原数组后执行 adjustLinkPosition('twitter', 2); console.log(links); // 输出结果: // [ // { link: "google", sort: 0 }, // { link: "facebook", sort: 1 }, // { link: "twitter", sort: 2 }, // { link: "ios", sort: 3 }, // { link: "android", sort: 3 }, // ]
内容的提问来源于stack exchange,提问作者Wolfdog
相关产品推荐
相关产品推荐

