将范围扩展到x个范围

时间:2017-11-20 10:22:25

标签: java scala vavr

我一直在打破这个

我想创建一个范围列表(作为Tuple2实例),其范围在minmax之间,分为numberOfIntervals

这个特殊的项目是在java(不允许scala),所以我使用vavr,但任何scala解决方案我都可能转换为vavr

这是我的解决方案:

final int numberOfIntervals = 7;

final int min = 1;
final int max = 100;

final int targetSize = (max - min) / numberOfIntervals + 1;
final List<Tuple2<Integer, Integer>> l = Iterator.rangeClosed(min, max)
        .grouped(targetSize)
        .map(l -> Tuple.of(l.head(), l.last())).toList();

这有效:

(1, 15)
(16, 30)
(31, 45)
(46, 60)
(61, 75)
(76, 90)
(91, 100)

但这是创建长中介列表。我也一直在玩这样的事情:

final int numberOfIntervals = 7;

final int min = 1;
final int max = 100;

final int targetSize = (max - min) / numberOfIntervals + 1;
final List<Tuple2<Integer, Integer>> l = Iterator
        .rangeClosedBy(min, max + targetSize, targetSize).sliding(2)
        .map(s -> of(s.get(0), s.get(1) - 1))
        .toList();

但是有了这个,最后一个范围大于最大值:

(1, 15)
(16, 30)
(31, 45)
(46, 60)
(61, 75)
(76, 90)
(91, 105)

2 个答案:

答案 0 :(得分:1)

你的第二个代码更好,但你不会因为最后一个间隔是例外而试图计算定期间隔的任何代码 - 但是你这样做,你必须以某种方式包含一个削减的条件它的大小。

我建议使用rangeBy代替rangeClosed,这样可以为您提供正确的起始元素集合。您已经拥有了区间大小,但不是硬编码+1(如果您的区间数除以范围大小而没有余数,则会产生不正确的结果),您可能需要使用Math.ceil()。之后,您只想将起始数字映射为map(x -> Tuple.of(x, Math.min(x + targetSize - 1, max)))

答案 1 :(得分:0)

根据Piotr Wilkin的建议,我想出了以下内容

final int numberOfIntervals = 7;

final int min = 1;
final int max = 100;

final int targetSize = (int) Math.ceil((max - min) / numberOfIntervals) ;
final List<Tuple2<Integer, Integer>> l = Iterator
        .rangeBy(min, max + targetSize, targetSize).sliding(2)
        .map(s -> of(s.get(0), s.get(1)-1))
        .map(t->t.map2(i->Math.min(i,max)))
        .toList();
相关问题