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

Javascript 基于双字段排序对象数组并重置order属性实现方案

需求说明

我们需要对一组对象数组按照以下规则排序并修改元素的order属性:

  • 所有relativePosition为Before的元素排在After元素之前
  • 同一mdmStep分类下,Before类元素的order从1开始顺序递增,After类元素的order单独从1开始重新顺序递增

现有错误代码

const data = [{
    "id": 0,
    "mdmStep": {
      "name": "Insert to Stage",
      "id": 1
    },
    "relativePosition": {
      "name": "After",
      "id": 2
    },
    "order": 1,
    "details": [{
      "commandText": "SELECT * FROM MDSRC_PRO_KOMODO_TRAN"
    }]
  },
  {
    "id": 3,
    "mdmStep": {
      "name": "Insert to Stage",
      "id": 1
    },
    "relativePosition": {
      "name": "Before",
      "id": 1
    },
    "order": 4,
    "details": [{
      "commandText": "SELECT * FROM MDSRC_PRO_KOMODO_CONFIG"
    }]
  },
  {
    "id": 1,
    "mdmStep": {
      "name": "Insert to Stage",
      "id": 1
    },
    "relativePosition": {
      "name": "After",
      "id": 2
    },
    "order": 2,
    "details": [{
      "commandText": "SELECT * FROM MDSRC_PRO_KOMODO_ADDR"
    }]
  },
  {
    "id": 2,
    "mdmStep": {
      "name": "Insert to Raw",
      "id": 2
    },
    "relativePosition": {
      "name": "After",
      "id": 2
    },
    "order": 3,
    "details": [{
      "commandText": "SELECT * FROM MDSRC_PRO_KOMODO_ADDR"
    }]
  },
  {
    "id": 4,
    "mdmStep": {
      "name": "Insert to Raw",
      "id": 2
    },
    "relativePosition": {
      "name": "After",
      "id": 2
    },
    "order": 5,
    "details": [{
      "commandText": "SELECT * FROM MDSRC_PRO_KOMODO_CONFIG"
    }]
  },
  {
    "id": 5,
    "mdmStep": {
      "name": "Update Match Fields",
      "id": 5
    },
    "relativePosition": {
      "name": "Before",
      "id": 1
    },
    "order": 6,
    "details": [{
      "commandText": "HELLO ARUN"
    }]
  }
]

const groups = _.groupBy(data, 'mdmStep.name')

const groupValues = _.reduce(_.keys(groups), (a, c) => {
  a[c] = _.orderBy(groups[c], 'relativePosition.id').map((i, idx) => {
    if (i.relativePosition.id === 1) {
      return {
        ...i,
        order: idx

      }
    }
    return {
      ...i,
      order: idx

    }
  });
  return a
}, {})

const changeOrders = _.orderBy(_.flattenDeep((_.map(_.keys(groupValues), group => {
  return _.map(groupValues[group], (i, index) => {
    return {
      ...i,
      order: index || index + 1
    }
  })

}))), 'mdmStep.id')

console.log(changeOrders)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

预期输出

[
    {
        "id": 3,
        "mdmStep": {
            "name": "Insert to Stage",
            "id": 1
        },
        "relativePosition": {
            "name": "Before",
            "id": 1
        },
        "order": 1,
        "details": [
            {
                "commandText": "SELECT * FROM MDSRC_PRO_KOMODO_CONFIG"
            }
        ]
    },
    {
        "id": 0,
        "mdmStep": {
            "name": "Insert to Stage",
            "id": 1
        },
        "relativePosition": {
            "name": "After",
            "id": 2
        },
        "order": 1,
        "details": [
            {
                "commandText": "SELECT * FROM MDSRC_PRO_KOMODO_TRAN"
            }
        ]
    },
    {
        "id": 1,
        "mdmStep": {
            "name": "Insert to Stage",
            "id": 1
        },
        "relativePosition": {
            "name": "After",
            "id": 2
        },
        "order": 2,
        "details": [
            {
                "commandText": "SELECT * FROM MDSRC_PRO_KOMODO_ADDR"
            }
        ]
    },
    {
        "id": 2,
        "mdmStep": {
            "name": "Insert to Raw",
            "id": 2
        },
        "relativePosition": {
            "name": "After",
            "id": 2
        },
        "order": 1,
        "details": [
            {
                "commandText": "SELECT * FROM MDSRC_PRO_KOMODO_ADDR"
            }
        ]
    },
    {
        "id": 4,
        "mdmStep": {
            "name": "Insert to Raw",
            "id": 2
        },
        "relativePosition": {
            "name": "After",
            "id": 2
        },
        "order": 2,
        "details": [
            {
                "commandText": "SELECT * FROM MDSRC_PRO_KOMODO_CONFIG"
            }
        ]
    },
    {
        "id": 5,
        "mdmStep": {
            "name": "Update Match Fields",
            "id": 5
        },
        "relativePosition": {
            "name": "Before",
            "id": 1
        },
        "order": 1,
        "details": [
            {
                "commandText": "HELLO ARUN"
            }
        ]
    }
]
问题排查与正确实现

原有代码问题

  1. 分组内赋值order时没有区分Before和After的独立计数序列,直接用全局索引赋值,导致After的计数没有从1重新开始
  2. 最后二次修改order的逻辑错误覆盖了分组内的赋值结果,分组逻辑用name而非id作为键也存在潜在的重复风险

正确实现代码

const result = _(data)
  // 按mdmStep.id分组,同分类元素聚合
  .groupBy('mdmStep.id')
  // 所有分组按mdmStep.id升序排列
  .orderBy(group => group[0].mdmStep.id)
  // 遍历每个分组处理排序和order赋值
  .flatMap(group => {
    // 组内先按relativePosition.id升序,保证Before在前
    const sortedInGroup = _.orderBy(group, 'relativePosition.id')
    let beforeCount = 1
    let afterCount = 1
    return sortedInGroup.map(item => {
      const newItem = {...item}
      // 分别维护Before和After的计数
      if (item.relativePosition.id === 1) {
        newItem.order = beforeCount++
      } else {
        newItem.order = afterCount++
      }
      return newItem
    })
  })
  .value()

console.log(result)

运行上述代码即可得到完全符合要求的输出结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 06:36:03