X-Git-Url: http://nitlanguage.org diff --git a/lib/core/collection/abstract_collection.nit b/lib/core/collection/abstract_collection.nit index aca4fdc..5f9af05 100644 --- a/lib/core/collection/abstract_collection.nit +++ b/lib/core/collection/abstract_collection.nit @@ -177,6 +177,21 @@ interface Collection[E] for e in self do if self.count(e) != other.count(e) then return false return true end + + # Does the collection contain at least one element of `other`? + # + # assert [1,3,4,2].has_any([1..10]) == true + # assert [1,3,4,2].has_any([5..10]) == false + # + # Note that the default implementation is general and correct for any lawful Collections. + # It is memory-efficient but relies on `has` so may be CPU-inefficient for some kind of collections. + fun has_any(other: Collection[nullable Object]): Bool + do + for o in other do + if has(o) then return true + end + return false + end end # Iterators generate a series of elements, one at a time. @@ -394,6 +409,7 @@ end # assert s.has(b) == true interface Set[E] super SimpleCollection[E] + super Cloneable redef fun has_only(item) do @@ -456,6 +472,8 @@ interface Set[E] return nhs end + redef fun clone do return union(self) + # Returns a new instance of `Set`. # # Depends on the subclass, mainly used for copy services @@ -794,6 +812,44 @@ interface SequenceRead[E] # REQUIRE `index >= 0 and index < length` fun [](index: Int): E is abstract + # Return the index-th element but wrap + # + # Whereas `self[]` requires the index to exists, the `modulo` accessor automatically + # wraps overbound and underbouds indexes. + # + # ~~~ + # var a = [10,20,30] + # assert a.modulo(1) == 20 + # assert a.modulo(3) == 10 + # assert a.modulo(-1) == 30 + # assert a.modulo(-10) == 30 + # ~~~ + # + # REQUIRE `not_empty` + # ENSURE `result == self[modulo_index(index)]` + fun modulo(index: Int): E do return self[modulo_index(index)] + + # Returns the real index for a modulo index. + # + # ~~~ + # var a = [10,20,30] + # assert a.modulo_index(1) == 1 + # assert a.modulo_index(3) == 0 + # assert a.modulo_index(-1) == 2 + # assert a.modulo_index(-10) == 2 + # ~~~ + # + # REQUIRE `not_empty` + fun modulo_index(index: Int): Int + do + var length = self.length + if index >= 0 then + return index % length + else + return length - (-1 - index) % length - 1 + end + end + # Get the last item. # Is equivalent with `self[length-1]`. # @@ -853,18 +909,13 @@ interface SequenceRead[E] # assert a.last_index_of_from(20, 2) == 1 # assert a.last_index_of_from(20, 1) == 1 # assert a.last_index_of_from(20, 0) == -1 - fun last_index_of_from(item: nullable Object, pos: Int): Int - do - var res = -1 - var p = 0 - var i = iterator - while i.is_ok do - if p>pos then break - if i.item == item then res = p - i.next - p += 1 + fun last_index_of_from(item: nullable Object, pos: Int): Int do + var i = pos + while i >= 0 do + if self[i] == item then return i + i -= 1 end - return res + return -1 end # Two sequences are equals if they have the same items in the same order. @@ -1049,6 +1100,24 @@ interface Sequence[E] # REQUIRE `index >= 0 and index <= length` fun []=(index: Int, item: E) is abstract + # Set the index-th element but wrap + # + # Whereas `self[]=` requires the index to exists, the `modulo` accessor automatically + # wraps overbound and underbouds indexes. + # + # ~~~ + # var a = [10,20,30] + # a.modulo(1) = 200 + # a.modulo(3) = 100 + # a.modulo(-1) = 300 + # a.modulo(-10) = 301 + # assert a == [100, 200, 301] + # ~~~ + # + # REQUIRE `not_empty` + # ENSURE `self[modulo_index(index)] == value` + fun modulo=(index: Int, value: E) do self[modulo_index(index)] = value + # Insert an element at a given position, following elements are shifted. # # var a = [10, 20, 30, 40]