Skip to content

Commit f05e32b

Browse files
committed
Added overload IndexOf and LastIndexOf
1 parent 72dfc6a commit f05e32b

File tree

5 files changed

+125
-46
lines changed

5 files changed

+125
-46
lines changed

Source/HproseCommon.pas

Lines changed: 93 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* *
1515
* hprose common unit for delphi. *
1616
* *
17-
* LastModified: Dec 18, 2016 *
17+
* LastModified: Dec 19, 2016 *
1818
* Author: Ma Bingyao <andot@hprose.com> *
1919
* *
2020
\**********************************************************/
@@ -90,8 +90,12 @@ EArrayListError = class(Exception);
9090
function GetCount: Integer;
9191
function Contains(const Value: Variant): Boolean;
9292
function GetEnumerator: IListEnumerator;
93-
function IndexOf(const Value: Variant): Integer;
94-
function LastIndexOf(const Value: Variant): Integer;
93+
function IndexOf(const Value: Variant): Integer; overload;
94+
function IndexOf(const Value: Variant; StartIndex: Integer): Integer; overload;
95+
function IndexOf(const Value: Variant; StartIndex, ACount: Integer): Integer; overload;
96+
function LastIndexOf(const Value: Variant): Integer; overload;
97+
function LastIndexOf(const Value: Variant; StartIndex: Integer): Integer; overload;
98+
function LastIndexOf(const Value: Variant; StartIndex, ACount: Integer): Integer; overload;
9599
function Join(const Glue: string = ',';
96100
const LeftPad: string = '';
97101
const RightPad: string = ''): string;
@@ -200,8 +204,12 @@ TAbstractList = class(TInterfacedObject, IList, IInvokeableVarObject)
200204
function Get(Index: Integer): Variant; virtual; abstract;
201205
procedure Put(Index: Integer; const Value: Variant); virtual; abstract;
202206
function GetEnumerator: IListEnumerator; virtual;
203-
function IndexOf(const Value: Variant): Integer; virtual; abstract;
204-
function LastIndexOf(const Value: Variant): Integer; virtual; abstract;
207+
function IndexOf(const Value: Variant): Integer; overload; virtual;
208+
function IndexOf(const Value: Variant; StartIndex: Integer): Integer; overload; virtual;
209+
function IndexOf(const Value: Variant; StartIndex, ACount: Integer): Integer; overload; virtual; abstract;
210+
function LastIndexOf(const Value: Variant): Integer; overload; virtual;
211+
function LastIndexOf(const Value: Variant; StartIndex: Integer): Integer; overload; virtual;
212+
function LastIndexOf(const Value: Variant; StartIndex, ACount: Integer): Integer; overload; virtual; abstract;
205213
procedure Insert(Index: Integer; const Value: Variant); virtual; abstract;
206214
procedure InsertRange(Index: Integer; const AList: IImmutableList); overload; virtual; abstract;
207215
procedure InsertRange(Index: Integer; const Container: Variant); overload; virtual; abstract;
@@ -275,8 +283,8 @@ TArrayList = class(TAbstractList, IArrayList)
275283
procedure Exchange(Index1, Index2: Integer); override;
276284
function Get(Index: Integer): Variant; override;
277285
procedure Put(Index: Integer; const Value: Variant); override;
278-
function IndexOf(const Value: Variant): Integer; override;
279-
function LastIndexOf(const Value: Variant): Integer; override;
286+
function IndexOf(const Value: Variant; StartIndex, ACount: Integer): Integer; overload; override;
287+
function LastIndexOf(const Value: Variant; StartIndex, ACount: Integer): Integer; overload; override;
280288
procedure Insert(Index: Integer; const Value: Variant); override;
281289
procedure InsertRange(Index: Integer; const AList: IImmutableList); overload; override;
282290
procedure InsertRange(Index: Integer; const Container: Variant); overload; override;
@@ -320,9 +328,9 @@ THashBucket = class(TObject)
320328
procedure Clear;
321329
procedure Delete(HashCode, Index: Integer);
322330
function IndexOf(HashCode: Integer; const Value: Variant;
323-
CompareProc: TIndexCompareMethod): Integer;
331+
CompareProc: TIndexCompareMethod; StartIndex, ACount: Integer): Integer;
324332
function LastIndexOf(HashCode: Integer; const Value: Variant;
325-
CompareProc: TIndexCompareMethod): Integer;
333+
CompareProc: TIndexCompareMethod; StartIndex, ACount: Integer): Integer;
326334
function Modify(OldHashCode, NewHashCode, Index: Integer): PHashItem;
327335
property Count: Integer read FCount;
328336
property Capacity: Integer read FCapacity write SetCapacity;
@@ -357,8 +365,8 @@ THashedList = class(TArrayList, IHashedList)
357365
procedure DeleteRange(Index, ACount: Integer); override;
358366
procedure Exchange(Index1, Index2: Integer); override;
359367
procedure Put(Index: Integer; const Value: Variant); override;
360-
function IndexOf(const Value: Variant): Integer; override;
361-
function LastIndexOf(const Value: Variant): Integer; override;
368+
function IndexOf(const Value: Variant; StartIndex, ACount: Integer): Integer; overload; override;
369+
function LastIndexOf(const Value: Variant; StartIndex, ACount: Integer): Integer; overload; override;
362370
procedure Insert(Index: Integer; const Value: Variant); override;
363371
procedure InsertRange(Index: Integer; const AList: IImmutableList); overload; override;
364372
procedure InsertRange(Index: Integer; const Container: Variant); overload; override;
@@ -2448,6 +2456,17 @@ destructor TAbstractList.Destroy;
24482456
inherited Destroy;
24492457
end;
24502458

2459+
function TAbstractList.IndexOf(const Value: Variant): Integer;
2460+
begin
2461+
Result := IndexOf(Value, 0, Count);
2462+
end;
2463+
2464+
function TAbstractList.IndexOf(const Value: Variant;
2465+
StartIndex: Integer): Integer;
2466+
begin
2467+
Result := IndexOf(Value, StartIndex, Count - StartIndex);
2468+
end;
2469+
24512470
procedure TAbstractList.InitLock;
24522471
begin
24532472
if not Assigned(FLock) then
@@ -2716,6 +2735,17 @@ function TAbstractList.Last: Variant;
27162735
Result := Get(Count - 1);
27172736
end;
27182737

2738+
function TAbstractList.LastIndexOf(const Value: Variant): Integer;
2739+
begin
2740+
Result := LastIndexOf(Value, Count - 1, Count);
2741+
end;
2742+
2743+
function TAbstractList.LastIndexOf(const Value: Variant;
2744+
StartIndex: Integer): Integer;
2745+
begin
2746+
Result := LastIndexOf(Value, StartIndex, StartIndex + 1);
2747+
end;
2748+
27192749
procedure TAbstractList.Pack;
27202750
var
27212751
I: Integer;
@@ -2939,23 +2969,15 @@ function TArrayList.IndexCompare(Index: Integer;
29392969
Result := VarEquals(FList[Index], Value);
29402970
end;
29412971

2942-
function TArrayList.IndexOf(const Value: Variant): Integer;
2972+
function TArrayList.IndexOf(const Value: Variant; StartIndex,
2973+
ACount: Integer): Integer;
29432974
var
2944-
I: Integer;
2945-
begin
2946-
for I := 0 to FCount - 1 do
2947-
if IndexCompare(I, Value) then begin
2948-
Result := I;
2949-
Exit;
2950-
end;
2951-
Result := -1;
2952-
end;
2953-
2954-
function TArrayList.LastIndexOf(const Value: Variant): Integer;
2955-
var
2956-
I: Integer;
2975+
I, EndIndex: Integer;
29572976
begin
2958-
for I := FCount - 1 downto 0 do
2977+
if StartIndex < 0 then StartIndex := 0;
2978+
EndIndex := StartIndex + ACount - 1;
2979+
if EndIndex >= FCount then EndIndex := FCount - 1;
2980+
for I := StartIndex to EndIndex do
29592981
if IndexCompare(I, Value) then begin
29602982
Result := I;
29612983
Exit;
@@ -3018,6 +3040,22 @@ procedure TArrayList.InsertRange(Index: Integer; const ConstArray: array of cons
30183040
Inc(FCount, N);
30193041
end;
30203042

3043+
function TArrayList.LastIndexOf(const Value: Variant; StartIndex,
3044+
ACount: Integer): Integer;
3045+
var
3046+
I, EndIndex: Integer;
3047+
begin
3048+
if StartIndex >= FCount then StartIndex := FCount - 1;
3049+
EndIndex := StartIndex - ACount + 1;
3050+
if EndIndex < 0 then EndIndex := 0;
3051+
for I := StartIndex downto EndIndex do
3052+
if IndexCompare(I, Value) then begin
3053+
Result := I;
3054+
Exit;
3055+
end;
3056+
Result := -1;
3057+
end;
3058+
30213059
procedure TArrayList.Move(CurIndex, NewIndex: Integer);
30223060
var
30233061
Elem: Variant;
@@ -3224,16 +3262,21 @@ procedure THashBucket.Grow;
32243262
end;
32253263

32263264
function THashBucket.IndexOf(HashCode: Integer; const Value: Variant;
3227-
CompareProc: TIndexCompareMethod): Integer;
3265+
CompareProc: TIndexCompareMethod; StartIndex, ACount: Integer): Integer;
32283266
var
3267+
EndIndex: Integer;
32293268
HashIndex: Integer;
32303269
Item: PHashItem;
32313270
begin
3271+
if StartIndex < 0 then StartIndex := 0;
3272+
EndIndex := StartIndex + ACount - 1;
3273+
if EndIndex >= FCount then EndIndex := FCount - 1;
32323274
Result := -1;
32333275
HashIndex := GetHashIndex(HashCode);
32343276
Item := FIndices[HashIndex];
32353277
while Assigned(Item) do begin
3236-
if (Item^.HashCode = HashCode) and CompareProc(Item^.Index, Value) then begin
3278+
if Item^.Index > EndIndex then Exit;
3279+
if (Item^.Index >= StartIndex) and (Item^.HashCode = HashCode) and CompareProc(Item^.Index, Value) then begin
32373280
Result := Item^.Index;
32383281
Exit;
32393282
end;
@@ -3242,18 +3285,23 @@ function THashBucket.IndexOf(HashCode: Integer; const Value: Variant;
32423285
end;
32433286

32443287
function THashBucket.LastIndexOf(HashCode: Integer; const Value: Variant;
3245-
CompareProc: TIndexCompareMethod): Integer;
3288+
CompareProc: TIndexCompareMethod; StartIndex, ACount: Integer): Integer;
32463289
var
3290+
EndIndex: Integer;
32473291
HashIndex: Integer;
32483292
Item: PHashItem;
32493293
begin
3294+
if StartIndex >= FCount then StartIndex := FCount - 1;
3295+
EndIndex := StartIndex - ACount + 1;
3296+
if EndIndex < 0 then EndIndex := 0;
32503297
Result := -1;
32513298
HashIndex := GetHashIndex(HashCode);
32523299
Item := FIndices[HashIndex];
32533300
if not Assigned(Item) then Exit;
32543301
Item := Item^.Prev;
32553302
repeat
3256-
if (Item^.HashCode = HashCode) and CompareProc(Item^.Index, Value) then begin
3303+
if Item^.Index < EndIndex then Exit;
3304+
if (Item^.Index <= StartIndex) and (Item^.HashCode = HashCode) and CompareProc(Item^.Index, Value) then begin
32573305
Result := Item^.Index;
32583306
Exit;
32593307
end;
@@ -3401,16 +3449,6 @@ function THashedList.HashOf(const Value: Variant): Integer;
34013449
Result := HashOfVariant(Value);
34023450
end;
34033451

3404-
function THashedList.IndexOf(const Value: Variant): Integer;
3405-
begin
3406-
Result := FHashBucket.IndexOf(HashOf(Value), Value, {$IFDEF FPC}@{$ENDIF}IndexCompare);
3407-
end;
3408-
3409-
function THashedList.LastIndexOf(const Value: Variant): Integer;
3410-
begin
3411-
Result := FHashBucket.LastIndexOf(HashOf(Value), Value, {$IFDEF FPC}@{$ENDIF}IndexCompare);
3412-
end;
3413-
34143452
procedure THashedList.InsertHash(Index, N: Integer);
34153453
var
34163454
HashCode, NewHashCode, I: Integer;
@@ -3426,6 +3464,14 @@ procedure THashedList.InsertHash(Index, N: Integer);
34263464
end;
34273465
end;
34283466

3467+
function THashedList.IndexOf(const Value: Variant; StartIndex,
3468+
ACount: Integer): Integer;
3469+
begin
3470+
Result := FHashBucket.IndexOf(HashOf(Value), Value,
3471+
{$IFDEF FPC}@{$ENDIF}IndexCompare, StartIndex, ACount);
3472+
3473+
end;
3474+
34293475
procedure THashedList.Insert(Index: Integer; const Value: Variant);
34303476
begin
34313477
inherited Insert(Index, Value);
@@ -3455,6 +3501,13 @@ procedure THashedList.InsertRange(Index: Integer; const ConstArray: array of con
34553501
InsertHash(Index, Length(ConstArray));
34563502
end;
34573503

3504+
function THashedList.LastIndexOf(const Value: Variant; StartIndex,
3505+
ACount: Integer): Integer;
3506+
begin
3507+
Result := FHashBucket.LastIndexOf(HashOf(Value), Value,
3508+
{$IFDEF FPC}@{$ENDIF}IndexCompare, StartIndex, ACount);
3509+
end;
3510+
34583511
procedure THashedList.Put(Index: Integer; const Value: Variant);
34593512
var
34603513
HashCode, I: Integer;

Test/ArrayListTestCase.pas

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,16 +186,23 @@ procedure TArrayListTestCase.TestIndexOf;
186186
Check(L.IndexOf(1) = 0);
187187
Check(L.IndexOf(3.14) = 2);
188188
Check(L.IndexOf(False) = -1);
189+
Check(L.IndexOf('abc') = 1);
190+
Check(L.IndexOf('abc', 1) = 1);
191+
Check(L.IndexOf('abc', 2) = 4);
192+
Check(L.IndexOf('abc', 2, 2) = -1);
189193
end;
190194

191195
procedure TArrayListTestCase.TestLastIndexOf;
192196
var
193197
L: IList;
194198
begin
195199
L := ArrayList([1, 'abc', 3.14, True, 'abc']);
196-
Check(L.LastIndexOf('abc') = 4);
197200
Check(L.LastIndexOf(1) = 0);
198201
Check(L.LastIndexOf('hello') = -1);
202+
Check(L.LastIndexOf('abc') = 4);
203+
Check(L.LastIndexOf('abc', 3) = 1);
204+
Check(L.LastIndexOf('abc', 4) = 4);
205+
Check(L.LastIndexOf('abc', 3, 2) = -1);
199206
end;
200207

201208
procedure TArrayListTestCase.TestDelete;

Test/CaseInsensitiveArrayListTestCase.pas

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,25 @@ procedure TCaseInsensitiveArrayListTestCase.TestIndexOf;
3737
L := CaseInsensitiveArrayList([1, 'Abc', 3.14, True, 'ABC']);
3838
Check(L.IndexOf(1.0) = -1);
3939
Check(L.IndexOf(1) = 0);
40-
Check(L.IndexOf('abc') = 1);
4140
Check(L.IndexOf(3.14) = 2);
4241
Check(L.IndexOf(False) = -1);
42+
Check(L.IndexOf('abc') = 1);
43+
Check(L.IndexOf('abc', 1) = 1);
44+
Check(L.IndexOf('abc', 2) = 4);
45+
Check(L.IndexOf('abc', 2, 2) = -1);
4346
end;
4447

4548
procedure TCaseInsensitiveArrayListTestCase.TestLastIndexOf;
4649
var
4750
L: IList;
4851
begin
4952
L := CaseInsensitiveArrayList([1, 'Abc', 3.14, True, 'ABC']);
50-
Check(L.LastIndexOf('abc') = 4);
5153
Check(L.LastIndexOf(1) = 0);
5254
Check(L.LastIndexOf('hello') = -1);
55+
Check(L.LastIndexOf('abc') = 4);
56+
Check(L.LastIndexOf('abc', 3) = 1);
57+
Check(L.LastIndexOf('abc', 4) = 4);
58+
Check(L.LastIndexOf('abc', 3, 2) = -1);
5359
end;
5460

5561
procedure TCaseInsensitiveArrayListTestCase.TestRemove;

Test/CaseInsensitiveHashedListTestCase.pas

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,25 @@ procedure TCaseInsensitiveHashedListTestCase.TestIndexOf;
3737
L := CaseInsensitiveHashedList([1, 'Abc', 3.14, True, 'ABC']);
3838
Check(L.IndexOf(1.0) = -1);
3939
Check(L.IndexOf(1) = 0);
40-
Check(L.IndexOf('abc') = 1);
4140
Check(L.IndexOf(3.14) = 2);
4241
Check(L.IndexOf(False) = -1);
42+
Check(L.IndexOf('abc') = 1);
43+
Check(L.IndexOf('abc', 1) = 1);
44+
Check(L.IndexOf('abc', 2) = 4);
45+
Check(L.IndexOf('abc', 2, 2) = -1);
4346
end;
4447

4548
procedure TCaseInsensitiveHashedListTestCase.TestLastIndexOf;
4649
var
4750
L: IList;
4851
begin
4952
L := CaseInsensitiveHashedList([1, 'Abc', 3.14, True, 'ABC']);
50-
Check(L.LastIndexOf('abc') = 4);
5153
Check(L.LastIndexOf(1) = 0);
5254
Check(L.LastIndexOf('hello') = -1);
55+
Check(L.LastIndexOf('abc') = 4);
56+
Check(L.LastIndexOf('abc', 3) = 1);
57+
Check(L.LastIndexOf('abc', 4) = 4);
58+
Check(L.LastIndexOf('abc', 3, 2) = -1);
5359
end;
5460

5561
procedure TCaseInsensitiveHashedListTestCase.TestRemove;

Test/HashedListTestCase.pas

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,23 @@ procedure THashedListTestCase.TestIndexOf;
187187
Check(L.IndexOf(1) = 0);
188188
Check(L.IndexOf(3.14) = 2);
189189
Check(L.IndexOf(False) = -1);
190+
Check(L.IndexOf('abc') = 1);
191+
Check(L.IndexOf('abc', 1) = 1);
192+
Check(L.IndexOf('abc', 2) = 4);
193+
Check(L.IndexOf('abc', 2, 2) = -1);
190194
end;
191195

192196
procedure THashedListTestCase.TestLastIndexOf;
193197
var
194198
L: IList;
195199
begin
196200
L := HashedList([1, 'abc', 3.14, True, 'abc']);
197-
Check(L.LastIndexOf('abc') = 4);
198201
Check(L.LastIndexOf(1) = 0);
199202
Check(L.LastIndexOf('hello') = -1);
203+
Check(L.LastIndexOf('abc') = 4);
204+
Check(L.LastIndexOf('abc', 3) = 1);
205+
Check(L.LastIndexOf('abc', 4) = 4);
206+
Check(L.LastIndexOf('abc', 3, 2) = -1);
200207
end;
201208

202209
procedure THashedListTestCase.TestDelete;

0 commit comments

Comments
 (0)