Delphi - есть ли лучший способ получить сокращения штатов из названий штатов - PullRequest
5 голосов
/ 29 апреля 2010

const
states : array [0..49,0..1] of string =
(
('Alabama','AL'),
('Montana','MT'),
('Alaska','AK'),
('Nebraska','NE'),
('Arizona','AZ'),
('Nevada','NV'),
('Arkansas','AR'),
('New Hampshire','NH'),
('California','CA'),
('New Jersey','NJ'),
('Colorado','CO'),
('New Mexico','NM'),
('Connecticut','CT'),
('New York','NY'),
('Delaware','DE'),
('North Carolina','NC'),
('Florida','FL'),
('North Dakota','ND'),
('Georgia','GA'),
('Ohio','OH'),
('Hawaii','HI'),
('Oklahoma','OK'),
('Idaho','ID'),
('Oregon','OR'),
('Illinois','IL'),
('Pennsylvania','PA'),
('Indiana','IN'),
('Rhode Island','RI'),
('Iowa','IA'),
('South Carolin','SC'),
('Kansas','KS'),
('South Dakota','SD'),
('Kentucky','KY'),
('Tennessee','TN'),
('Louisiana','LA'),
('Texas','TX'),
('Maine','ME'),
('Utah','UT'),
('Maryland','MD'),
('Vermont','VT'),
('Massachusetts','MA'),
('Virginia','VA'),
('Michigan','MI'),
('Washington','WA'),
('Minnesota','MN'),
('West Virginia','WV'),
('Mississippi','MS'),
('Wisconsin','WI'),
('Missouri','MO'),
('Wyoming','WY')
);
function getabb(state:string):string;
var
  I:integer;
begin
  for I := 0 to length(states) -1 do
  if lowercase(state) = lowercase(states[I,0]) then
  begin
    result:= states[I,1];
  end;
end;
function getstate(state:string):string;
var
  I:integer;
begin
  for I := 0 to length(states) -1 do
  if lowercase(state) = lowercase(states[I,1]) then
  begin
    result:= states[I,0];
  end;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
 edit1.Text:=getabb(edit1.Text);
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
 edit1.Text:=getstate(edit1.Text);
end;

end.

Есть ли лучший способ сделать это?

Ответы [ 4 ]

8 голосов
/ 29 апреля 2010

Должен ли этот тип данных быть жестко закодирован?
Не лучше ли использовать что-то вроде XML-файла или даже просто CSV.

или пары значений имени, т.е. IA = Айова
затем загружается в TStringList для получения

States.Values['IA'] = 'Iowa';

Тогда вам просто нужно написать что-то для поиска значений, чтобы работать в обратном направлении, как

//***Untested***
//Use: NameOfValue(States, 'Iowa') = 'IA'

function NameOfValue(const strings: TStrings; const Value: string): string;
var
  i : integer;
  P: Integer;
  S: string;
begin
  for i := 0 to strings.count - 1 do
  begin
    S := strings.ValueFromIndex[i];
    P := AnsiPos(strings.NameValueSeparator, S);
    if (P <> 0) and (AnsiCompareText(Copy(S, 1, P - 1), Value) = 0) then
     begin
      Result := strings.Names[i];
      Exit;
     end;
  end;
  Result := '';
end;

Я вполне уверен, что регистр не учитывается

7 голосов
/ 29 апреля 2010

Если вы используете D2009 или D2010, используйте TDictionary<string, string> из Generics.Collections. Объявите массив констант так, как он у вас есть, затем настройте словарь, поместив каждую пару в словарь. Затем просто используйте свойство словаря по умолчанию для поиска.

2 голосов
/ 29 апреля 2010

Обратите внимание, что нижний регистр (a) = нижний регистр (b) медленнее, чем sameText (a, b).

Кроме того, вы можете еще больше ускорить процедуру, сохранив строки в массиве только в нижнем регистре, а затем в процедуре поиска начните с преобразования входных данных в нижний регистр. Тогда вы можете использовать еще более быструю функцию sameStr (a, b). Но, конечно, когда совпадение найдено, вам необходимо отформатировать его, используя заглавные буквы. Такой ускоренный подход, вероятно, не очень важен для такого небольшого списка строк. В конце концов, в США не так много штатов.

Кроме того, вы должны объявлять функции, используя константные аргументы, т.е. писать

function getabb(const state:string):string;

вместо

function getabb(state:string):string;

(если вы не хотите изменить состояние в подпрограмме).

Наконец, вы можете сделать код более компактным и читаемым, пропустив begin и end циклов for.

1 голос
/ 30 апреля 2010

Я бы отсортировал ваши списки. Таким образом, вы можете использовать бинарный поиск , чтобы сократить время поиска. Все зависит от количества итераций, которые вы будете выполнять. Около 50 элементов не кажутся такими уж большими, пока вы несколько раз не перебираете список, не ища последний элемент в списке.

Также вы должны ВСЕГДА освобождать залог от своих петель, как только вы получите совпадение, если знаете, что остальная часть списка не будет соответствовать.

Массивы в порядке, и в зависимости от того, как вы используете данные, вам может понадобиться добавить некоторые "территории", которые также имеют сокращений (PR = PUERTO RICO, GU = GUAM и т. Д.) .

...