当前位置: 首页 > 知识库问答 >
问题:

汇总列表中的每N个元素?

毋修为
2023-03-14

我有一个这样的数字列表:

[ 0, 1, 2, 3, 4, 5, 6, 7 ]

如何以优雅的方式总结每个N(让我们假设2)个元素并将列表转换为:

[ 1, 5, 9, 13 ]

编辑:我想出了以下解决方案

    List<Double> input = Arrays.asList(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0);
    List<Double> output = new ArrayList<>();

    int N = 2;
    IntStream.range(0, (input.size() + N - 1) / N)
            .mapToObj(i -> input.subList(i * N, Math.min(N * (i + 1), input.size())))
            .mapToDouble(l -> l.stream().mapToDouble(Double::doubleValue).sum())
            .forEach(output::add);

    System.out.println(output);

它是有效的,但我仍然在寻找一个更易读、更简单的方法。

共有3个答案

葛骏
2023-03-14

下面是另一种方法,使用<code>收集器。groupingBy():

List<Integer> numbers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7);
int N = 2;
Collection<Integer> sums =  numbers.stream()
                                   .collect(Collectors.groupingBy(i-> i/N,
                                                                  Collectors.summingInt(Integer::intValue)))
                                   .values();
System.out.println (sums);

输出:

[1, 5, 9, 13]
郑茂勋
2023-03-14

鉴于:

List<Integer> numbers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7);
int nth = 2;

怎么样:

IntStream.iterate(0, idx -> idx + nth)
         .limit(numbers.size() / nth)
         .map(idx -> IntStream.range(idx, idx + nth)
                              .reduce((sum, index) -> sum + numbers.get(index))
                              .orElse(0))
         .forEach(System.out::println);

或者替代地:

IntStream.range(0, numbers.size() / nth)
         .map(idx -> IntStream.range(idx * nth, (idx + 1) * nth)
                              .map(index -> numbers.get(index))
                              .sum())
         .forEach(System.out::println);
邹海荣
2023-03-14

这是另一种方法,无论您的元素是否排序,它都有效。此外,它不会对您的起始值进行任何预测,并在更广泛的范围内给出正确的结果。即使list.size()%n==0条件不成立,这种方法仍然有效。因此,从字面上看,它不需要任何先决条件来保持以获得所需的内容。

这种方法背后的直觉是,您的索引是自然排序的,因此可以用来实现我们所需要的。我们可以将元素分组到一个类别中,只要它们当前的索引i / n产生相同的值。然后,使用下游收集器计算属于同一组中的元素的总和。这是它的外观。

Collection<Integer> sumsOfnElements = IntStream.range(0, numbers.size()).boxed()
    .collect(Collectors.groupingBy(i -> i / n, 
        Collectors.summingInt(numbers::get))).values(); 

下面给出了遵循或多或少相同方法的等效迭代解。在性能严格的设置中,我会选择此命令式解决方案,而不是基于流的解决方案。

假设:输入是整数数组,而不是列表。

final float inputLen = input.length;
final int resultLen = (int) Math.ceil(inputLen / n);
final int[] result = new int[resultLen];

for (int i = 0; i < inputLen; i++)
    result[i / n] += input[i];
 类似资料:
  • 问题内容: 我有这样的结构: 我想使用内置方法(在一行中)对整数()求和。 有任何想法吗? 问题答案: 会工作。

  • 问题内容: 这是我的代码,我需要对列表中未定义数量的元素求和。这该怎么做? 我的输入: 输入后,我通过删除第一个元素。在列表之后,我需要对列表中的所有元素求和。 在这种情况下,总和为18。请注意,未定义元素数。 问题答案: 您可以使用内置的sum()来对列表中的数字求和: 它将汇总所有数量的项目。例: 对于您的具体情况 : 对于您的数据,首先将数字转换为数字,然后将数字求和: 这将适用于列表中 未

  • 问题内容: 例如,是否可以选择一组元素中的每个第四个元素? 例如:我有16个元素…我可以写类似的东西。 有一个更好的方法吗? 问题答案: 顾名思义,它允许您使用除常数以外的变量构造算术表达式。您可以执行加法(),减法()和系数乘法(其中是整数,包括正数,负数和零)。 这是重写上面的选择器列表的方法: 有关这些算术表达式如何工作的解释,请参见我对该问题的回答以及规范。 请注意,此答案假设同一父元素内

  • 问题内容: 在MySQL中,我有两个表: 和 我需要对表(等式7)和表(等式3)中的列求和,并将结果作为总数量。 当我做 我得到了笛卡尔积(20),但是我需要的正确答案是10。如何更改此查询以获得正确的结果? 问题答案:

  • 问题内容: 假设 如何获得由每n行之和组成的新系列? 当n = 5时,预期结果如下所示; 如果使用loc或iloc并通过python循环,当然可以完成,但是我相信可以简单地以Pandas方式完成。 另外,这是一个非常简化的示例,我不希望对序列进行解释:)。我正在尝试的实际数据系列具有时间索引和每秒发生的事件数作为值。 问题答案: 将索引分为5组,并相应地分组。 + 如果大小是N的倍数(或5),则可

  • 本文向大家介绍OCaml 汇总列表中的数据,包括了OCaml 汇总列表中的数据的使用技巧和注意事项,需要的朋友参考一下 示例 的List.fold_left和List.fold_right功能是实现列表聚集的外逻辑高阶函数。汇总列表(有时也称为简化列表)意味着计算从对该列表中所有项目的顺序检查得出的值。 列表模块的文档指出: List.fold_left f a [b1; ...; bn]是f (