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

JavaScript如何将对象中的多类数组元素按每组n个均等分组

水果分盒问题解决方案

实现思路

  • 优先统计所有水果总数量,若总数量≤单盒最大容量n,直接返回1个装全量水果的盒子即可
  • 为每类水果创建独立的拷贝队列,避免分配操作修改原始数据
  • 采用轮询取果逻辑:按固定顺序循环从仍有剩余的水果队列中取1个放入当前盒子,盒子装满n个就存入结果并开启新盒子
  • 该取法天然保证不同品类水果尽可能均匀分布,不会出现单类水果集中在少数盒子的问题

完整代码实现

无依赖原生JS版本

function distributeFruits(fruitBox, n) {
  // 拷贝每类水果生成独立队列,不修改原始数据
  const fruitQueues = Object.values(fruitBox).map(list => [...list]);
  // 统计总水果数
  const totalFruitCount = fruitQueues.reduce((sum, queue) => sum + queue.length, 0);
  // 总数量小于等于单盒容量,直接返回一个盒子
  if (totalFruitCount <= n) {
    return [fruitQueues.flat()];
  }
  const resultBoxes = [];
  let currentBox = [];
  let typeIndex = 0;
  const totalTypeCount = fruitQueues.length;
  // 循环直到所有水果分配完成
  while (fruitQueues.some(queue => queue.length > 0)) {
    const currentTypeQueue = fruitQueues[typeIndex];
    // 当前品类还有剩余则取一个放入当前盒子
    if (currentTypeQueue.length > 0) {
      currentBox.push(currentTypeQueue.shift());
      // 当前盒子装满则存入结果,开启新盒子
      if (currentBox.length === n) {
        resultBoxes.push(currentBox);
        currentBox = [];
      }
    }
    // 轮询到下一个品类
    typeIndex = (typeIndex + 1) % totalTypeCount;
  }
  // 存入最后一个未装满的盒子(如果有)
  if (currentBox.length > 0) {
    resultBoxes.push(currentBox);
  }
  return resultBoxes;
}

测试用例(匹配题目示例)

const boxOfFruits = {
  apples: [
    { name: "Kashmiri" },
    { name: "Washington" },
    { name: "Himalayan" },
    { name: "Fuji" }
  ],
  oranges: [
    { name: "Nagpur" },
    { name: "Clementine" }
  ],
  mangoes: [
    { name: "Totapuri" },
    { name: "Alphonso" },
    { name: "Langda" }
  ]
};
// 单盒最多放3个
const distributedBoxes = distributeFruits(boxOfFruits, 3);
console.log(distributedBoxes);
/* 输出结果完全符合预期:
[
  [ {name: 'Kashmiri'}, {name: 'Nagpur'}, {name: 'Totapuri'} ],
  [ {name: 'Washington'}, {name: 'Clementine'}, {name: 'Alphonso'} ],
  [ {name: 'Himalayan'}, {name: 'Langda'}, {name: 'Fuji'} ]
]
*/

Lodash 简化版本

如果你已经在项目中使用Lodash,可以用以下简化实现:

const _ = require('lodash');
function distributeFruitsLodash(fruitBox, n) {
  const fruitQueues = _.mapValues(fruitBox, list => [...list]);
  const fruitTypes = _.keys(fruitQueues);
  const totalFruitCount = _.sumBy(fruitTypes, type => fruitQueues[type].length);
  if (totalFruitCount <= n) return [_.flatten(_.values(fruitQueues))];
  const resultBoxes = [];
  let currentBox = [];
  let typeIndex = 0;
  const totalTypeCount = fruitTypes.length;
  while (_.some(fruitTypes, type => fruitQueues[type].length > 0)) {
    const currentType = fruitTypes[typeIndex];
    if (fruitQueues[currentType].length) {
      currentBox.push(fruitQueues[currentType].shift());
      if (currentBox.length === n) {
        resultBoxes.push(currentBox);
        currentBox = [];
      }
    }
    typeIndex = (typeIndex + 1) % totalTypeCount;
  }
  currentBox.length && resultBoxes.push(currentBox);
  return resultBoxes;
}

方案特性

  • 支持动态增减水果品类,无需修改代码,自动识别所有传入对象的键
  • 支持任意自定义单盒最大容量n
  • 自动兼容总水果数小于n的场景,仅返回1个盒子
  • 轮询取果逻辑保证不同品类水果分布尽可能均匀,无扎堆问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 09:57:02