Есть ли способ найти индекс элемента массива указателей?
Есть ли способ найти индекс элемента массива указателей?
Код выглядит так:
type
TArrayItem = record
Field1: string;
Field2: integer;
Field3: boolean;
end;
var
MyItem: TArrayItem;
MyArray: array[1..100] of TArrayItem;
Допустим, я беру элемент из массива (MyItem:=MyArray[20];
). После этого я сортирую массив и расположение элементов меняется; Теперь, как я могу найти новый индекс MyItem
?
2 ответа
У вас нет массива указателей. В отличие от class
, который является ссылочным типом, record
это тип значения Как вы объявили массив, данные элемента копируются всякий раз, когда вы делаете назначение. Итак, когда вы назначаете элемент массива MyItem
Вы делаете копию данных этого элемента, но не получаете указатель на исходный элемент.
В любом случае, если у вас есть массив элементов или массив указателей на элементы, ответ один и тот же: единственный способ найти элемент в массиве - это циклически просмотреть массив вручную, например:
var
MyItem: TArrayItem;
MyArray: array[1..100] of TArrayItem;
I: Integer;
MyItem := MyArray[20];
// sort the array...
for I := Low(MyArray) to High(MyArray) do
begin
if (MyArray[I].Field1 = MyItem.Field1) and
(MyArray[I].Field2 = MyItem.Field2) and
(MyArray[I].Field3 = MyItem.Field3) then
begin
// item was found at index I...
end;
end;
В противном случае, динамически размещайте ваши элементы в куче и сохраняйте их указатели в TList
или же TList<T>
как они выставляют IndexOf()
методы. И сортировка будет быстрее, поскольку вы перемещаете указатели, а не полные копии данных.
Не существует встроенной механики для выполнения того, что вы просите. Вам придется перебирать массив и идентифицировать соответствующий элемент, чтобы определить его положение в этом массиве.
В этом случае вы также должны заметить, что, хотя в вашем вопросе говорится, что у вас есть "массив указателей", код, который вы опубликовали, - это не массив указателей, а массив записей, которые являются типами значений, а не ссылками, поэтому этот код:
MyItem := MyArray[20];
Не получает ссылку на 20-й элемент в MyArray, а создает его копию. Код для идентификации элемента в массиве довольно заметно меняется, когда вы находите копию элемента по сравнению со ссылкой на элемент.
Чтобы найти элемент в массиве указателей:
var
i, indexOfItem: Integer;
item: ^TArrayItem;
theArray: array[1..100] of ^TArrayItem;
item := theArray[20];
indexOfItem := -1;
for i := Low(theArray) to High(theArray) do
if (theArray[i] = item) then
begin
indexOfItem := i;
BREAK;
end;
Чтобы найти элемент в массиве записей, вы должны проверить равенство полей записей отдельно, поскольку вы не можете сравнить две записи в целом:
var
i, indexOfItem: Integer;
item: TArrayItem;
theArray: array[1..100] of TArrayItem;
item := theArray[20];
indexOfItem := -1;
for i := Low(theArray) to High(theArray) do
if (theArray[i].Field1 = item.Field1)
and (theArray[i].Field2 = item.Field2)
and (theArray[i].Field3 = item.Field3) then
begin
indexOfItem := i;
BREAK;
end;
Вы также должны знать, что в этом последнем случае есть встроенное предположение, что никакие два элемента не будут иметь одинаковые значения для полей записи, поскольку будет идентифицирован только первый соответствующий элемент.
NB. Приведенный выше код не предназначен для того, чтобы быть надежными решениями, а только для демонстрации соответствующих принципов.
Еще одна вещь, о которой следует помнить, это вероятность того, что у вас есть массив записей, но вы получили указатель на какой-то элемент в этом массиве до сортировки массива:
var
item: ^TArrayItem;
theArray: array[1..100] of TArrayItem;
item := @theArray[20];
SortTheArray(theArray);
Если это так, то после сортировки массива (или любой формы манипулирования этим массивом) значение указателя элемента может перестать быть надежным для динамического массива, поскольку массив мог перемещаться в памяти в результате операции, выполненные на нем!
Даже если массив не перемещался, как в настоящее время в случае статического массива, указатель элемента будет указывать на тот элемент, который сейчас находится на 20-й позиции в этом массиве, а не на элементе, который был в этой позиции до сортировки.