【发布时间】:2011-12-21 17:47:06
【问题描述】:
我有一个我想划分为子集的项目列表。为了讨论,让我们说它们是文件。我希望每个子集最多包含 5 个文件,并且如果可能的话,子集中文件的总大小小于 1 MB。如果单个文件超过 1MB,则它应该单独位于一个子集中。
我以更通用的形式写了这篇文章,使用通用的“项目度量”而不是文件大小。但我怀疑有一种更简单和/或更好的方法可以做到这一点。有什么建议么?
这是我得到的:
public static IEnumerable<IEnumerable<T>> InSetsOf<T>(this IEnumerable<T> source, int maxItemsPerSet, int maxMetricPerSet, Func<T, int> getMetric)
{
int currentMetricSum = 0;
List<T> currentSet = new List<T>();
foreach (T listItem in source)
{
int itemMetric = getMetric(listItem);
if (currentSet.Count > 0 &&
(currentSet.Count >= maxItemsPerSet || (currentMetricSum + itemMetric) > maxMetricPerSet))
{
yield return currentSet;
//Start a new subset
currentSet = new List<T>();
currentMetricSum = 0;
}
currentSet.Add(listItem);
currentMetricSum += itemMetric;
}
//Return the last set
yield return currentSet;
}
【问题讨论】:
-
如果您正在寻找最佳选择,这是经典的bin packing problem。看起来您已经实现了首次拟合(没有预排序)。问题是您是在寻找更简洁的代码还是更好的解决方案?如果是前者,您可能会在Code Review SE 获得更好的运气。
-
@Oded - Take and Skip 不会检查额外的指标(在我的示例中是文件大小)。
-
@RonWarholic - 我认为这个问题必须有一个名称,谢谢!我最感兴趣的是更简洁的代码。在我的实际用例中,最佳分布并不是很重要。
标签: c# .net ienumerable yield-return