Scala中是否有范围数据结构?

时间:2016-04-26 11:19:55

标签: scala range rangeset

我正在寻找一种处理Scala范围的方法。 我需要做的是:

给定一组范围和范围(A)返回范围(B),其中范围(A)相交范围(B)不为空

给定一组范围和范围(A)从/向范围集移除/添加范围(A)。

给定范围(A)和范围(B)创建范围(C)= [min(A,B),max(A,B)]

我在java中看到类似的内容 - http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/RangeSet.html 虽然subRangeSet仅返回交叉值,而不返回与其相交的集合(或范围列表)中的范围。

 RangeSet rangeSet = TreeRangeSet.create();
 rangeSet.add(Range.closed(0, 10));
 rangeSet.add(Range.closed(30, 40));
 Range range = Range.closed(12, 32);
 System.out.println(rangeSet.subRangeSet(range)); //[30,32] (I need [30,40])
 System.out.println(range.span(Range.closed(30, 40))); //[12,40]

2 个答案:

答案 0 :(得分:5)

spire math library中有Interval[A]类型。这允许使用定义Order的任意类型的范围。边界可以是包含的,排他的或省略的。所以例如(-∞, 0.0][0.0, 1.0)可能是双倍的间隔。

这是一个库intervalset,用于处理多个非重叠区间(IntervalSeqIntervalTrie)以及间隔到任意值的映射(IntervalMap

这是一个related question,它描述了如何将IntervalSeq与DateTime一起使用。

请注意,如果您要使用的类型是64位或更少(基本上是任何原语),IntervalTrie 非常快。请参阅Benchmarks

答案 1 :(得分:2)

正如Tzach Zohar在评论中提到的,如果您需要的是Int的范围 - 去scala.collection.immutable.Range:

val rangeSet = Set(0 to 10, 30 to 40)
val r = 12 to 32
rangeSet.filter(range => range.contains(r.start) ||  range.contains(r.end))

如果你需要它用于另一种基础类型 - 自己实现它,它对你的用例来说很容易。