const task = [
{ x: 1, y: 20 },
{ x: 2, y: 30 },
{ x: 1, y: 50 },
{ x: 2, y: 20 },
{ x: 1, y: 10 },
{ x: 9, y: 40 },
{ x: 1, y: 30 },
{ x: 3, y: 5 }
];
有两个条件:
- 分组限制可以是max z
- y 的总和可以是最大值 t
例如 z=2
和 t=60
(我将这些值作为参数传递给函数),结果应该是:
let result = [
[{ x: 1, y: 20 },{ x: 2, y: 30 }],
[{ x: 1, y: 50 }],
[{ x: 2, y: 20 },{ x: 1, y: 10 }],
[{ x: 9, y: 40 }],
[{ x: 1, y: 30 },{ x: 3, y: 5 }]
];
我已经设法用 for
循环实现,但我对可能的功能解决方案感到好奇。如有任何帮助,我们将不胜感激。
最佳答案
一种稍微更实用的方法将包括一些非常简单的纯助手。让我们从函数 ySum
开始,它返回给定参数 group
中所有 y
属性的总和:
const ySum = (group) => group.reduce((sum, { y: currY }) => sum + currY, 0);
接下来,让我们定义一个函数,它接受一个任务和一个组,并告诉我们给定的任务是否适合也给定的组:
根据评论更新 此函数始终为空组返回 true 以防止当 y > 60
特定任务时出现空数组问题/p>
const taskFitsInGroup = (task, group) => {
if (group.length === 0) {
return true;
}
return (group.length < 2) && (ySum(group) + task.y <= 60);
};
注意:您当然可以将常量 2
和 60
提取到变量/参数。
Array.prototype.reduce是您需要的数据转换的理想选择。在 addTask
实现后,下面这行应该可以满足您的要求:
const result = tasks.reduce(addTask, [[]]);
唯一剩下要做的就是创建我们为上面的 reduce
提供的 addTask
函数。使用我们已经创建的辅助函数,这实际上非常简单:
const addTask = (accumulation, task) => {
const lastGroup = accumulation[accumulation.length - 1];
if (taskFitsInGroup(task, lastGroup)) {
lastGroup.push(task);
} else {
accumulation.push([task]);
}
return accumulation;
};
工作示例:
const tasks = [
{ x: 1, y: 80 },
{ x: 2, y: 30 },
{ x: 1, y: 50 },
{ x: 2, y: 20 },
{ x: 1, y: 10 },
{ x: 9, y: 40 },
{ x: 1, y: 30 },
{ x: 3, y: 5 },
];
const ySum = (group) => group.reduce((sum, { y: currY }) => sum + currY, 0);
const taskFitsInGroup = (task, group) => {
if (group.length === 0) {
return true;
}
return (group.length < 2) && (ySum(group) + task.y <= 60);
};
const addTask = (accumulation, task) => {
const lastGroup = accumulation[accumulation.length - 1];
if (taskFitsInGroup(task, lastGroup)) {
lastGroup.push(task);
} else {
accumulation.push([task]);
}
return accumulation;
};
const result = tasks.reduce(addTask, [[]]);
console.log(result);
关于javascript - 具有多个条件的数组动态分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48572255/