如何用 N 个分区而不是大小为 N 的分区对列表进行分区?
How to partition a list with N partitions rather than partitions of size N?
Guava 的方法,Lists#partition
,将 List<?>
划分为 List<List<?>>
,其中每个分区包含 N
个元素(由函数的第二个参数指定,并且不包括最后一个分区)。
是否可以使用此方法但改为创建 N
个分区?
如果没有,有什么方法可以解决?
我试图用以下内容创建 31
个分区(keys
是 List<String>
大小 57
),但它只创建 29
:
List<String> keys = ...;
var paritions = Lists.partition(keys, (int) Math.ceil(keys.size() / 31D));
要创建 N 个分区,您必须至少有 2N 个元素。在您的情况下,您的分区要求为 31,这意味着您需要 62 个元素。
因为你有 57 个元素,所以你有五个元素 - 或者两个半分区 - 低于所需的最小值,这就是为什么你得到 29 个分区,最后一个分区只有一个元素。
番石榴正在做它的工作。您没有足够的元素来正确细分成您想要的分区。
问题在于您的自定义分区分配 "empty space"(即由于缺少完全填充分区的元素而留下的间隙)与 Guava 的方法不同。该方法将在创建下一个分区之前完全填充每个分区,而您希望均匀分布元素。这是因为 partition()
定义了组的 size,而你想指定组的 number。
看看这个自定义实现:
private static <T> List<List<T>> distribute(List<T> elements, int nrOfGroups)
{
int elementsPerGroup = elements.size() / nrOfGroups;
int leftoverElements = elements.size() % nrOfGroups;
List<List<T>> groups = new ArrayList<>();
for (int i = 0; i < nrOfGroups; i++)
{
groups.add(elements.subList(i * elementsPerGroup + Math.min(i, leftoverElements),
(i + 1) * elementsPerGroup + Math.min(i + 1, leftoverElements)));
}
return groups;
}
它将计算组的最小大小(floor of count/#groups),然后在有剩余元素的情况下更正前几个组的大小。
例子
List<Integer> elements = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
int nrOfGroups = 6;
// [[1, 2], [3, 4], [5], [6], [7], [8]]
Guava 的方法,Lists#partition
,将 List<?>
划分为 List<List<?>>
,其中每个分区包含 N
个元素(由函数的第二个参数指定,并且不包括最后一个分区)。
是否可以使用此方法但改为创建 N
个分区?
如果没有,有什么方法可以解决?
我试图用以下内容创建 31
个分区(keys
是 List<String>
大小 57
),但它只创建 29
:
List<String> keys = ...;
var paritions = Lists.partition(keys, (int) Math.ceil(keys.size() / 31D));
要创建 N 个分区,您必须至少有 2N 个元素。在您的情况下,您的分区要求为 31,这意味着您需要 62 个元素。
因为你有 57 个元素,所以你有五个元素 - 或者两个半分区 - 低于所需的最小值,这就是为什么你得到 29 个分区,最后一个分区只有一个元素。
番石榴正在做它的工作。您没有足够的元素来正确细分成您想要的分区。
问题在于您的自定义分区分配 "empty space"(即由于缺少完全填充分区的元素而留下的间隙)与 Guava 的方法不同。该方法将在创建下一个分区之前完全填充每个分区,而您希望均匀分布元素。这是因为 partition()
定义了组的 size,而你想指定组的 number。
看看这个自定义实现:
private static <T> List<List<T>> distribute(List<T> elements, int nrOfGroups)
{
int elementsPerGroup = elements.size() / nrOfGroups;
int leftoverElements = elements.size() % nrOfGroups;
List<List<T>> groups = new ArrayList<>();
for (int i = 0; i < nrOfGroups; i++)
{
groups.add(elements.subList(i * elementsPerGroup + Math.min(i, leftoverElements),
(i + 1) * elementsPerGroup + Math.min(i + 1, leftoverElements)));
}
return groups;
}
它将计算组的最小大小(floor of count/#groups),然后在有剩余元素的情况下更正前几个组的大小。
例子
List<Integer> elements = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
int nrOfGroups = 6;
// [[1, 2], [3, 4], [5], [6], [7], [8]]