You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS重排数组元素 实现相同key对象不相邻排列

数组重排需求说明
  • 输入:所有元素均为单key对象的数组myArray
  • 排序规则:
    • 优先调整元素位置,尽可能保证相邻两个对象的key不重复
    • 若某类key的元素总数超过数组长度的1/2,无法实现完全间隔排列时,剩余的同key元素统一追加到数组末尾
  • 参考期望效果(以morning/evening两类key为例):
const finalArray = [
  {"morning": "..."},
  {"evening": "..."},
  {"morning": "..."},
  {"evening": "..."},
  {"morning": "..."},
  {"evening": "..."},
  {"morning": "..."},
  {"evening": "..."},
  {"evening": "..."},
  {"evening": "..."}
]
原有代码问题分析

原有实现存在3个核心缺陷,是导致排序中途混乱的根本原因:

  • 未提前按key对元素做分组统计,直接按原数组遍历顺序判断插入,也没有优先安排元素数量最多的key,很容易提前耗尽数量少的key,导致大量同key元素提前堆积
  • 存在重复插入逻辑漏洞:首个元素初始化插入orderedArray后,后续遍历key的逻辑没有跳过该元素,会触发重复判断、重复插入
  • 放入unOrderedArray的元素未做二次校验,直接拼接时可能出现拼接位置前后key相同的问题
正确实现方案

核心实现逻辑:先按key对所有元素分组,每次插入元素时,优先选择和上一个插入元素key不同、且剩余元素数量最多的分组取元素插入,直到找不到符合间隔要求的元素,再把所有剩余元素统一追加到数组末尾。

const myArray = [{
  "morning": "23_6557"
}, {
  "evening": "7665_908"
}, {
  "evening": "545_787"
}, {
  "evening": "8774_957"
}, {
  "morning": "434_6447"
}, {
  "morning": "775_67"
}, {
  "evening": "4554_8774"
}, {
  "evening": "224_74"
}, {
  "evening": "43_112"
}, {
  "morning": "32_47"
}]

function rearrangeArray(arr) {
  // 按key对元素分组
  const groupMap = new Map()
  arr.forEach(item => {
    const key = Object.keys(item)[0]
    if (!groupMap.has(key)) groupMap.set(key, [])
    groupMap.get(key).push(item)
  })
  // 分组按剩余元素数量降序排序
  let groups = Array.from(groupMap.entries())
    .map(([key, list]) => ({key, list}))
    .sort((a, b) => b.list.length - a.list.length)

  const result = []
  let lastKey = null

  while (groups.length) {
    // 查找第一个符合间隔要求的非空分组
    const targetIndex = groups.findIndex(group => group.key !== lastKey && group.list.length)
    // 找不到可间隔插入的元素,终止循环
    if (targetIndex === -1) break

    // 取出元素插入结果集
    const targetGroup = groups[targetIndex]
    result.push(targetGroup.list.shift())
    lastKey = targetGroup.key

    // 过滤空分组,重新按剩余数量排序
    groups = groups.filter(group => group.list.length)
      .sort((a, b) => b.list.length - a.list.length)
  }

  // 拼接剩余无法间隔插入的元素
  const rest = groups.flatMap(group => group.list)
  return [...result, ...rest]
}

const finalArray = rearrangeArray(myArray)
console.log(finalArray)

针对给出的测试用例,上述代码运行后会输出完全符合预期的结果:前8位交替排列morning和evening类元素,剩余2个evening类元素追加在末尾,不会出现相邻同key的排序混乱问题。

内容的提问来源于stack exchange,提问作者seriously

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 05:54:17