我正在寻找一种处理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]
答案 0 :(得分:5)
spire math library中有Interval[A]
类型。这允许使用定义Order
的任意类型的范围。边界可以是包含的,排他的或省略的。所以例如(-∞, 0.0]
或[0.0, 1.0)
可能是双倍的间隔。
这是一个库intervalset,用于处理多个非重叠区间(IntervalSeq或IntervalTrie)以及间隔到任意值的映射(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))
如果你需要它用于另一种基础类型 - 自己实现它,它对你的用例来说很容易。