Delphi как в массиве найти элемент

I wrote one I modeled after the old Clipper AScan function (tested in XE). @RRUZ’s answer is more correct (there is one existing), but mine doesn’t require the array to be sorted first and is fast enough on small arrays. (It also works in pre-generics versions of Delphi.) I also overload it for various types of array – here are the implementations for string and integer:

// Returns the 0-based index of Value if it's found in the array,
// -1 if not. (Similar to TStrings.IndexOf)
function AScan(const Ar: array of string; const Value: string): Integer; overload;
var
  i: Integer;
begin
  Result := -1;
  for i := Low(Ar) to High(Ar) do
    if SameText(Ar[i], Value) then
    begin
      Result := i;
      Break
    end;
end;

function AScan(const Ar: array of Integer; const Value: Integer): Integer; overload;
var
  i: Integer;
begin
  Result := -1;
  for i := Low(Ar) to High(Ar) do
    if (Ar[i] = Value) then
    begin
      Result := i;
      Break
    end;
end;

procedure TForm2.FormShow(Sender: TObject);
var
  someStrArray: TArray<string>;
  someIntArray: TArray<Integer>;
  Idx: Integer;
begin
  someStrArray := TArray<string>.Create('One', 'Two', 'Three');
  Idx := AScan(someStrArray, 'Two');
  if Idx > -1 then
    ShowMessage(Format('It contains Two at index %d', [Idx]))
  else
    ShowMessage('Not found');
  someIntArray := TArray<Integer>.Create(8, 16, 32);
  Idx := AScan(someIntArray, 32);
  if Idx > -1 then
    ShowMessage(Format('It contains 32 at %d', [Idx]))
  else
    ShowMessage('16 not found');
end;

For versions of Delphi that support generics, here’s a version that doesn’t require the array to be sorted, and that also allows you to provide the comparison function if needed:

Interface:

type
  TGenericsUtils = class
  public
    class function AScan<T>(const Arr: array of T; const Value: T; const Comparer: IEqualityComparer<T>):  Integer; overload;
    class function AScan<T>(const Arr: array of T; const Value: T): Integer; overload;
  end;

Implementation

class function TGenericsUtils.AScan<T>(const Arr: array of T; const Value: T): Integer;
begin
  Result := AScan<T>(Arr, Value, TEqualityComparer<T>.Default);
end;

class function TGenericsUtils.AScan<T>(const Arr: array of T; const Value: T;
  const Comparer: IEqualityComparer<T>): Integer;
var
  i: Integer;
begin
  for i := Low(Arr) to High(Arr) do
    if Comparer.Equals(Arr[i], Value) then
      Exit(i);
  Exit(-1);
end;

Test code:

var
  AIntTest: TIntegerDynArray;
  AStrTest: TStringDynArray;

begin
  AIntTest := TIntegerDynArray.Create(12, 15, 6, 1, 4, 9, 5);
  AStrTest := TStringDynArray.Create('One', 'Six', 'Three', 'Four', 'Twelve');
  WriteLn('AIntTest contains 9 at index ', TGenericsUtils.AScan<Integer>(AIntTest, 9));
  WriteLn('AStrTest contains ''Four'' at index ', TGenericsUtils.AScan<String>(AStrTest, 'Four'));
  ReadLn;
end.

You could also write a Generic version, however you can’t use generics with stand-alone procedures, they need to be bound to a class or record. Something like the following

unit Generics.ArrayUtils;

interface

uses
  System.Generics.Defaults;

type
  TArrayUtils<T> = class
  public
    class function Contains(const x : T; const anArray : array of T) : boolean;
  end;

implementation

{ TArrayUtils<T> }

class function TArrayUtils<T>.Contains(const x: T; const anArray: array of T): boolean;
var
  y : T;
  lComparer: IEqualityComparer<T>;
begin
  lComparer := TEqualityComparer<T>.Default;
  for y in anArray do
  begin
    if lComparer.Equals(x, y) then
      Exit(True);
  end;
  Exit(False);
end;

end.

usage would be

procedure TForm6.Button1Click(Sender: TObject);
begin
  if TArrayUtils<integer>.Contains(3, [1,2,3]) then
    ShowMessage('Yes')
  else
    ShowMessage('No');
end;

Should work with parameters like TArray<integer> or array of integer as well as constant arrays (shown) – and you could add many other methods to the class, such as IndexOf or Insert

From Delphi 10.3 you can omit the <integer> due to type inferencing so would look like TArrayUtils.Contains(3, [1,2,3]).

beginner03

0 / 0 / 0

Регистрация: 11.06.2020

Сообщений: 73

1

Найти элемент в массиве

26.06.2020, 07:27. Показов 1062. Ответов 9

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Не находит введенное число. Где ошибка ?

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids;
 
type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    StringGrid1: TStringGrid;
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
const
   size=5;
var
  Form1: TForm1;
     a: array [1..size] of integer;
      obr: integer;
     found: boolean;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var
   i: byte;
begin
//obr:=;
for i:=1 to SIZE do
a[i]:=StrToInt (StringGrid1.Cells[i-1,0]); //ââîä ìàññèâà obr:= StrToInt (Edit1.Text);
//ââîä îáðàçöà äëÿ ïîèñêà found:=false;
//ñ÷èòàåì, ÷òî íóæíîãî ýëåìåíòà íåò â ìàññèâå
 
i:=1;
repeat //â öèêëå íà÷èíàåì ñðàâíèâàòü
if a[i]=obr //êàæäûé I-ûé ýëåìåíò ñ îáðàçöîì
then found:=true
else i:=i+1;
until (i>SIZE) or (found=True);
 
if found
then ShowMessage ('Ñîâïàäåíèå ñ ýëåìåíòîì íîìåð ' +
IntToStr(i)+#13 + 'Ïîèñê óñïåøåí')
else ShowMessage ('Ñîâïàäåíèé ñ îáðàçöîì íåò');
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
close;
end;
end.



0



668 / 558 / 242

Регистрация: 26.11.2012

Сообщений: 2,190

26.06.2020, 08:50

2

Цитата
Сообщение от beginner03
Посмотреть сообщение

a[i]=obr

Чему равно obr?



0



Нарушитель

8584 / 4589 / 1058

Регистрация: 12.03.2015

Сообщений: 21,524

26.06.2020, 08:55

3

Прогони под отладчиком – сразу найдёшь.
Я, конечно, всё и так вижу.



0



0 / 0 / 0

Регистрация: 11.06.2020

Сообщений: 73

26.06.2020, 09:03

 [ТС]

4

Изначально в Edit1 в Text указано произвольное число. Ввожу любое из матрицы, не видит. Как инициализировать obr ?



0



AzAtom

Модератор

3366 / 1939 / 705

Регистрация: 15.11.2015

Сообщений: 7,716

26.06.2020, 09:07

5

Цитата
Сообщение от beginner03
Посмотреть сообщение

Как инициализировать obr ?

Эти строки как бы намекают, как инициализировать эту переменную:

Delphi
1
2
3
//obr:=;
...
a[i]:=StrToInt (StringGrid1.Cells[i-1,0]); //ââîä ìàññèâà obr:= StrToInt (Edit1.Text);

Зачем нужно было удалять инициализацию obr?



0



0 / 0 / 0

Регистрация: 11.06.2020

Сообщений: 73

26.06.2020, 09:17

 [ТС]

6

ранее уже присваивал 0, но всё равно не работает.

Добавлено через 6 минут
разобрался



0



0 / 0 / 0

Регистрация: 11.10.2021

Сообщений: 2

10.10.2022, 06:43

7

Брат пж мне помаги можешь этот проект скинуть пж брат



0



Модератор

3366 / 1939 / 705

Регистрация: 15.11.2015

Сообщений: 7,716

10.10.2022, 09:54

8

Hasan6, человек уже год не заходил на форум. Что здесь есть, то и бери.



0



0 / 0 / 0

Регистрация: 11.10.2021

Сообщений: 2

10.10.2022, 09:57

9

Я не знаю как эту ошибку исправить пж помаги буду благадарен



0



mr-Crocodile

2876 / 1532 / 618

Регистрация: 19.03.2019

Сообщений: 5,115

10.10.2022, 10:15

10

Цитата
Сообщение от Hasan6
Посмотреть сообщение

Я не знаю как эту ошибку исправить

какую – “эту” ?
Выложи свой код и конкретно укажи, что тебя в нём не устраивает.

ну и начни всё же с такого кода:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids;
 
type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    StringGrid1: TStringGrid;
    Edit1: TEdit;
    Button1: TButton;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
const
   ArraySize=5;
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var
   i, obr : integer;
   found: boolean;
   a: array [1..ArraySize] of integer;
begin
   //ввод образца для поиска 
  obr := StrToInt (Edit1.Text);
 
  //ввод массива из визуального компонента StringGrid1
  for i:=1 to ArraySize do
    a[i]:=StrToInt (StringGrid1.Cells[i-1,0]); 
 
  found:=false;  //считаем, что нужного элемента нет в массиве
 
  i:=1; // начинаем поиск с первого элемента массива
  repeat //в цикле начинаем сравнивать
     if a[i]=obr //каждый I-ый элемент с образцом
        then found:=true
     else i:=i+1;
  until (i>ArraySize) or (found=True);
 
  if found
    then ShowMessage ('Совпадение с элементом номер ' + IntToStr(i)+#13 + 'поиск успешен')
    else ShowMessage ('Совпадений с образцом нет');
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
   close;
end;
 
end.



1



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

10.10.2022, 10:15

Помогаю со студенческими работами здесь

В массиве найти последний отрицательный элемент
извините конечно, я снова прошу вас помочь с моей задачей: в заданном одномерном массиве найти…

В массиве из случайных чисел найти наибольший элемент
10-и элементная массив..Надо рандомно заполнять символы в массив и в массиве какой символ большой)…

В заданном одномерном массиве найти последний отрицательный элемент
В заданном одномерном массиве найти последний отрицательный элемент. Все нечетные элементы заменить…

Найти наибольший элемент и его индексы в двумерном массиве
Добрый день.

Есть вот такой код:
procedure TForm1.FormCreate(Sender: TObject);
const
x:array…

В одномерном массиве Х найти максимальный элемент среди положительных
1. 1. В массиве Х(3,5; -7,4; 23,7; 12,9; -5,6; 11,3; -8,6; 4,5; 0,6; 2,5) найти максимальный…

Найти наибольший отрицательный и наименьший элемент в одномерном массиве
Доброе утро народ помогите пожалуйста а то всю голову сломал уже. Я просто новичок в использовании…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

10

Delphi DevTips

Delphi development tips from real-life projects (yes those do exist!!!)

So the problem appeared today, when I wanted to see if a specific integer number appeared in an array of integers. Ok this feels a little bit too general, so let’s see the real life case.

I have a table with transportation vehicles where each vehicle is of specific type. Each vehicle type in the database is represented through an number(10) value which as you might understand it is a foreign key to another table. The request was to make a checking about specific data only when a vehicle is of specific types. Let’s say that those types are 1, 2, 3, 4, 7, 9, 10.

Having this in mind I decided to create a function that will find the vehicle type of a specific vehicle (this is not what it needs to be seen right now – meaning the select statements etc) and to check whether this type is one of the types the checking will take place.

To do this a function is created called VehicleIsSpecificType which will return a boolean and does the following:

function VehicleIsSpecificType(VehicleCodeId: Integer): Boolean;
var
  VehType: Variant;
  i: Integer;
const
  ValidTypesForChecking: array[0..6] of Integer = (1, 2, 3, 4, 7, 9, 10);
begin
  Result := False;
  {First find the vehicle type through the use of a select statement. 
   Not shown here as it's part of a specific ERP SDK}
  VehType := .....; //returned a Variant
  if not VarIsNull(VehType) then
    for i := 0 to Length(ValidTypesForChecking) - 1 do
      if i = VehType then begin
        Result := True;
        break;
      end;
end;

Of course the same thing can be done with other element types like strings or float values. Even with multidimensional arrays (which a second for loop will be needed – it will be shown in a future post)

Очень был удивлен когда к нам поступила
просьба рассказать о массивах и о их
сортировке в Delphi. Но раз уж поступила
просьба, а сайт наш призван помочь в
освоении Delphi, то я решил написать эту статью,
в которой расскажу Вам о возможных
действиях с массивами в Delphi. При этом мы
напишем несколько пользовательских
функций, которые будут помогать нам в
дальнейшем при работе с массивами.

Ввод массива

Для того чтобы работать с массивом, его
надо с начала получить от пользователя.
Попробуем осуществить ввод одномерного
массива всего в одно поле редактирования.
Каждый элемент массива будет отделяться от
предыдущего разделителем. После щелчка на
кнопке программа выделит из строки,
содержащей массив, первую подстроку,
затем выделит вторую подстроку и т.д.

Давайте сейчас этим и займемся. Поставьте
на Вашу форму кнопку Button и поле
редактирования Edit.

Заголовок нашей функции будет такой:

function GetSubStr(st:string; expl:string; n:integer):string; 

где

st – строка, содержащая массив
expl – строка разделитель
n – номер подстроки

function TForm1.GetSubStr(st:string; expl:string ;n:integer):string;
Var p,i:integer;
Begin
 for i:= 1 to n-1 do
 begin
  p:=pos(expl,st);
  st:=copy(st,p+1,Length(st)-p);
  while (pos(expl,st)=1) and (length(st)>0) do
   delete(st,1,1);
 end;
p:=pos(expl,st);
if p<>0 then result:=copy(st,1,p-1)
else result:=st;

End;

Для получения n-ой подстроки (элемента
массива) из полученной в качестве аргумента
строки функция сначала удаляет
предшествующую ей n-1 подстроку (цикл for),
затем находит разделитель, который
обозначает конец нужной подстроки,
выделяет подстроку и возвращает ее в
качестве значения функции (через свое имя).

Не забудьте добавить заголовок нашей
функции в раздел Public модуля программы.

Теперь для проверки работы нашей функции
напишем обработчик события OnClick, для
нашей кнопки. В начале мы с помощью нашей
функции получим массив из Edit1, а потом
выведем его:

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
a:array[1..10] of string[10];
st:string;
begin
for i:=1 to 10 do
a[i]:=GetSubStr(Edit1.text,' ',i);//используем пробел в
качестве разделителя

for i:=1 to 10 do
st:=st+IntTostr(i)+' '+a[i]+#13;
ShowMessage(st);
end;

Поиск минимального (максимального)
элемента массива

Будем искать минимальный элемент в
целочисленном массиве. Для этого немного
изменим обработчик события OnClick для
кнопки:

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;//номер элемента, сравниваемого с минимальным
a:array[1..10] of integer; 
min:integer;//номер минимального элемента

begin
//Введем массив
for i:=1 to 10 do
//Преобразуем полученные подстроки в числа
 a[i]:=StrToInt(GetSubStr(Edit1.text,' ',i));//используем пробел в качестве разделителя
//Найдем минимальный элемент
min:=1; //пусть номер минимального элемента = 1
for i:= 2 to 10 do // начнем искать со следующего 
 if a[i] < a[min] then min:=i;
Form1.caption:=IntToStr(a[min]); // выводим в заголовок
формы минимальный элемент
end;

В этом примере a[min] минимальный
элемент массива, а min – номер
минимального элемента. Алгоритм очень
простой: сравниваем каждый следующий
элемент с минимальным, если он меньше
минимального, то запоминаем его номер в
переменной min, и продолжаем сравнивать
уже с ним.

Чтобы найти максимальный
элемент, нужно изменить всего одну строку:

>>>
if a[i] < a[min] then min:=i;

Надо заменить на:

 if a[i] > a[min] then min:=i;

Только теперь a[min] – максимальный элемент,
а min – номер максимального элемента.

Поиск заданного элемента в массиве

Поступим методом простого перебора. Для
этого будем перебирать все элементы
массива, пока не встретим искомый элемент,
или пока не дойдем до конца массива.

Элемент,
совпадение с которым нам надо найти будем
хранить в текстовом поле Edit2. Обработчик
события OnClick нашей кнопки будет иметь такой
вид:

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
a:array[1..10] of integer;
n:integer;//образец
found:boolean;

begin
//Введем массив
for i:=1 to 10 do
//Преобразуем полученные подстроки в числа
 a[i]:=StrToInt(GetSubStr(Edit1.text,' ',i));//используем пробел в качестве разделителя


n:=StrToInt(Edit2.text);
found:=false;
i:=1;
REPEAT
if a[i] = n then found:=true
 else i:=i+1;
UNTIL (i > 10) or (found = true);
if found then showmessage('Совпадение с элементом номер '+IntToStr(i));
end;

Сортировка массива

Вот мы и дошли до самого интересного – до
сортировки массива. Рассмотрим алгоритм т.н.
прямого выбора. Смысл его заключается в
следующем:

Просматривая массив от первого элемента,
найдем минимальный элемент и поместим его
на место первого элемента, а первый
элемент – на место минимального.

Затем будем просматривать массив,
начиная со второго элемента, и далее
поступим, как поступили перед этим
шагом.

Алгоритм ясен, теперь приступим к
написанию кода. Все тот же обработчик
события OnClick принимает теперь такой вид:

procedure TForm1.Button1Click(Sender: TObject);
var i,k,j,min:integer;
buf:integer; // буфер для обмена
a:array[1..10] of integer;
st:string;
begin
//введем массив
for i:=1 to 10 do
a[i]:=StrToInt(GetSubStr(Edit1.text,' ',i));//используем пробел в качестве разделителя

for i:=1 to 10 - 1 do // кол-во элементов минус один
 begin
//поищем минимальный элемент
  min:=i;
  for j:=i+1 to 10 do
   if a[j] < a[min] then min:=j;
//поменяем местами
  buf:=a[i];
  a[i]:=a[min];
  a[min]:=buf;
 end;

for k:=1 to 10 do
Form1.Caption:=Form1.caption + ' '+ IntToStr(a[k]);
end;

Ну вот мы и познакомились с самыми
типичными действиями с массивами. Надеюсь
эта статья оказалась Вам хоть немного
полезной 🙂

Добавить комментарий