@@ -183,11 +183,15 @@ class IMAP
183
183
# - #max: Returns the maximum number in the set.
184
184
# - #minmax: Returns the minimum and maximum numbers in the set.
185
185
#
186
- # <i>Accessing value by (normalized) offset:</i>
186
+ # <i>Accessing value by offset in sorted set :</i>
187
187
# - #[] (aliased as #slice): Returns the number or consecutive subset at a
188
- # given offset or range of offsets.
189
- # - #at: Returns the number at a given offset.
190
- # - #find_index: Returns the given number's offset in the set
188
+ # given offset or range of offsets in the sorted set.
189
+ # - #at: Returns the number at a given offset in the sorted set.
190
+ # - #find_index: Returns the given number's offset in the sorted set.
191
+ #
192
+ # <i>Accessing value by offset in ordered entries</i>
193
+ # - #find_ordered_index: Returns the index of the given number's first
194
+ # occurrence in entries.
191
195
#
192
196
# <i>Set cardinality:</i>
193
197
# - #count (aliased as #size): Returns the count of numbers in the set.
@@ -1083,33 +1087,48 @@ def has_duplicates?
1083
1087
count_with_duplicates != count
1084
1088
end
1085
1089
1086
- # Returns the index of +number+ in the set, or +nil+ if +number+ isn't in
1087
- # the set.
1090
+ # Returns the (sorted and deduplicated) index of +number+ in the set, or
1091
+ # +nil+ if +number+ isn't in the set.
1088
1092
#
1089
- # Related: #[]
1093
+ # Related: #[], #at, #find_ordered_index
1090
1094
def find_index ( number )
1091
1095
number = to_tuple_int number
1092
- each_tuple_with_index do |min , max , idx_min |
1096
+ each_tuple_with_index ( @tuples ) do |min , max , idx_min |
1093
1097
number < min and return nil
1094
1098
number <= max and return from_tuple_int ( idx_min + ( number - min ) )
1095
1099
end
1096
1100
nil
1097
1101
end
1098
1102
1103
+ # Returns the first index of +number+ in the ordered #entries, or
1104
+ # +nil+ if +number+ isn't in the set.
1105
+ #
1106
+ # Related: #find_index
1107
+ def find_ordered_index ( number )
1108
+ number = to_tuple_int number
1109
+ each_tuple_with_index ( each_entry_tuple ) do |min , max , idx_min |
1110
+ if min <= number && number <= max
1111
+ return from_tuple_int ( idx_min + ( number - min ) )
1112
+ end
1113
+ end
1114
+ nil
1115
+ end
1116
+
1099
1117
private
1100
1118
1101
- def each_tuple_with_index
1119
+ def each_tuple_with_index ( tuples )
1102
1120
idx_min = 0
1103
- @tuples . each do |min , max |
1104
- yield min , max , idx_min , ( idx_max = idx_min + ( max - min ) )
1121
+ tuples . each do |min , max |
1122
+ idx_max = idx_min + ( max - min )
1123
+ yield min , max , idx_min , idx_max
1105
1124
idx_min = idx_max + 1
1106
1125
end
1107
1126
idx_min
1108
1127
end
1109
1128
1110
- def reverse_each_tuple_with_index
1129
+ def reverse_each_tuple_with_index ( tuples )
1111
1130
idx_max = -1
1112
- @ tuples. reverse_each do |min , max |
1131
+ tuples . reverse_each do |min , max |
1113
1132
yield min , max , ( idx_min = idx_max - ( max - min ) ) , idx_max
1114
1133
idx_max = idx_min - 1
1115
1134
end
@@ -1120,18 +1139,21 @@ def reverse_each_tuple_with_index
1120
1139
1121
1140
# :call-seq: at(index) -> integer or nil
1122
1141
#
1123
- # Returns a number from +self+, without modifying the set. Behaves the
1124
- # same as #[], except that #at only allows a single integer argument.
1142
+ # Returns the number at the given +index+ in the sorted set, without
1143
+ # modifying the set.
1144
+ #
1145
+ # +index+ is interpreted the same as in #[], except that #at only allows a
1146
+ # single integer argument.
1125
1147
#
1126
1148
# Related: #[], #slice
1127
1149
def at ( index )
1128
1150
index = Integer ( index . to_int )
1129
1151
if index . negative?
1130
- reverse_each_tuple_with_index do |min , max , idx_min , idx_max |
1152
+ reverse_each_tuple_with_index ( @tuples ) do |min , max , idx_min , idx_max |
1131
1153
idx_min <= index and return from_tuple_int ( min + ( index - idx_min ) )
1132
1154
end
1133
1155
else
1134
- each_tuple_with_index do |min , _ , idx_min , idx_max |
1156
+ each_tuple_with_index ( @tuples ) do |min , _ , idx_min , idx_max |
1135
1157
index <= idx_max and return from_tuple_int ( min + ( index - idx_min ) )
1136
1158
end
1137
1159
end
@@ -1146,17 +1168,18 @@ def at(index)
1146
1168
# seqset[range] -> sequence set or nil
1147
1169
# slice(range) -> sequence set or nil
1148
1170
#
1149
- # Returns a number or a subset from +self+, without modifying the set.
1171
+ # Returns a number or a subset from the _sorted_ set, without modifying
1172
+ # the set.
1150
1173
#
1151
1174
# When an Integer argument +index+ is given, the number at offset +index+
1152
- # is returned:
1175
+ # in the sorted set is returned:
1153
1176
#
1154
1177
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
1155
1178
# set[0] #=> 10
1156
1179
# set[5] #=> 15
1157
1180
# set[10] #=> 26
1158
1181
#
1159
- # If +index+ is negative, it counts relative to the end of +self+ :
1182
+ # If +index+ is negative, it counts relative to the end of the sorted set :
1160
1183
# set = Net::IMAP::SequenceSet["10:15,20:23,26"]
1161
1184
# set[-1] #=> 26
1162
1185
# set[-3] #=> 22
@@ -1168,13 +1191,14 @@ def at(index)
1168
1191
# set[11] #=> nil
1169
1192
# set[-12] #=> nil
1170
1193
#
1171
- # The result is based on the normalized set— sorted and de-duplicated— not
1172
- # on the assigned value of #string.
1194
+ # The result is based on the sorted and de-duplicated set, not on the
1195
+ # ordered #entries in #string.
1173
1196
#
1174
1197
# set = Net::IMAP::SequenceSet["12,20:23,11:16,21"]
1175
1198
# set[0] #=> 11
1176
1199
# set[-1] #=> 23
1177
1200
#
1201
+ # Related: #at
1178
1202
def []( index , length = nil )
1179
1203
if length then slice_length ( index , length )
1180
1204
elsif index . is_a? ( Range ) then slice_range ( index )
0 commit comments