Marcello Impastato
Marcello Impastato

Reputation: 2281

structured array and search

I need some suggestions for solving this problem. I have this data structure:

type
  QmyArray = array of integer;
  PmyArray = record
    element: Qmyarray;
    value: integer;
  end;
  TMyArray = array of Pmyarray;

var
  myarray: tmyArray;
  myvalue: qmyarray;

I set all values of myarray correctly, and all values of myarray.element are sorted correctly and this is fine. The problem I have is when I want search myvalue in myarray and get value. For searching, I use binarysearch and write:

tarray.BinarySearch(myarray, myvalue, index);

and of course it's not working. Because I understood that need customized the comparer so I write:

function CompareB(const Left, Right: integer): Integer;
begin
  if Left < Right then
    Result := -1
  else if Left > Right then
    Result := 1
  else
    Result := 0;
end;

function CompareA(const Left, Right: pmyarray): Integer;
var
  iIndex: Integer;
begin
  Result := CompareB(Left.element[0], Right.element[0]);
  for iIndex := 1 to High(Right.element) do
    if Result = 0 then
      Result := CompareB(Left.element[iIndex], Right.element[iIndex]);
end;

and try with:

tarray.BinarySearch(myarray, myvalue, index, TComparer<Pmyarray>.Construct(CompareA));

but in this case I receive this error:

[DCC Error] Project1.dpr(98): E2250 There is no overloaded version of 'BinarySearch' that can be called with these arguments

and I don't understand where I made a mistake.

How can I solve it?

Upvotes: 1

Views: 620

Answers (1)

Cosmin Prund
Cosmin Prund

Reputation: 25678

You have one sole error, the type of the myvalue variable should be PMyArray, not QmyArray. Next time you're facing such a problem try using the long-hand version of TArray.BinarySearch, so that Code Insight actually shows meaningful type names.

When you write:

TArray.BinarySearch(myarray, myvalue, index, iComparer)

the compiler needs to guess the type of your array from the parameters. If you missmatch the types of myarray and myvalue the compiler can't tell what you really wanted and code insight has no chance of actually showing you what it wants. But you can give it a hand by telling it the type of array you want to operate on, using this syntax:

TArray.BinarySearch<PmyArray>(myarray, myvalue, index, iComparer)

With this, the compiler knows you intend to deal with an array of PmyArray. Code insight also knows that and shows you the exact types of parameters it needs.

This works:

program Project9;

{$APPTYPE CONSOLE}

uses
  SysUtils, Generics.Collections, Generics.Defaults;

type
  QmyArray = array of Integer;
  PmyArray = record
    element: QmyArray;
    value: Integer;
  end;
  TMyArray = array of PmyArray;

var myarray: TMyArray;
    myvalue: PmyArray;
    FoundIndex: Integer;

function CompareB(const Left, Right: integer): Integer;
begin
  if Left < Right then
    Result := -1
  else if Left > Right then
    Result := 1
  else
    Result := 0;
end;

function CompareA(const Left, Right: pmyarray): Integer;
var
  iIndex: Integer;
begin
  Result := CompareB(Left.element[0], Right.element[0]);
  for iIndex := 1 to High(Right.element) do
    if Result = 0 then
      Result := CompareB(Left.element[iIndex], Right.element[iIndex]);
end;

begin
  TArray.BinarySearch<PmyArray>(myarray, myvalue, FoundIndex, TComparer<PmyArray>.Construct(CompareA));
end.

Upvotes: 4

Related Questions