Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сортировка файлов или папок, TSearchRec, Сортировка 
V
    Опции темы
Keeper89
Дата 29.10.2009, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



Доброго времени суток!

Есть функция, где происходит поиск файлов через TSearchRec. Далее в этой же функции планируется сортировка различного типа (по имени, дате создания, размеру и т.д. + убыв./возр.) и на выходе получается соотв. отсортированный список файлов в формате TStringList.

Подскажите, каким образом лучше осуществить сортировку и вообще организовать функцию?




--------------------
PM MAIL WWW   Вверх
Beltar
Дата 29.10.2009, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 3
Всего: 7



А просто сгрести все нужное содержимое к какую-то таблицу (например контейнер на основе TList, у него и сортировка есть) к которой потом применять сортировку с нужной функцией сравнения? Мне кажется это оптимальный способ т. к. сортировка выполниться всего один раз, а иначе придется каждый раз считав файл искать двоичным поиском его место в таблице.

Или я чего-то не понял?

Это сообщение отредактировал(а) Beltar - 29.10.2009, 00:21


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
Keeper89
Дата 29.10.2009, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



Beltar, небольшой пример можно?


--------------------
PM MAIL WWW   Вверх
Qu1nt
Дата 29.10.2009, 01:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 13.1.2007

Репутация: 18
Всего: 50



Код

uses
  Math;

function CompareDates(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := CompareValue(StrToDate(List[Index1]), StrToDate(List[Index2]));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  List: TStringList;
begin
  List := TStringList.Create;
  try
    List.Add('21.12.2012');
    List.Add('29.10.2009');
    List.Add('05.12.2010');
    List.CustomSort(CompareDates);
    ListBox1.Items.Assign(List);
  finally
    List.Free;
  end;
end;

PM MAIL   Вверх
Keeper89
Дата 29.10.2009, 02:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



Qu1nt, 
А где тогда будут храниться остальные данные (имена, даты создания и т.п.)?


--------------------
PM MAIL WWW   Вверх
Qu1nt
Дата 29.10.2009, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 13.1.2007

Репутация: 18
Всего: 50



Ты данные куда выводишь? В TListView? Тогда можно сделать сортировку по нажатию на колонку.
PM MAIL   Вверх
Keeper89
Дата 29.10.2009, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



Я, как говорил в 1 посте, вывожу только имена после сделанной сортировки.


--------------------
PM MAIL WWW   Вверх
Qu1nt
Дата 29.10.2009, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 13.1.2007

Репутация: 18
Всего: 50



Набросал, вот:
Код

{ by Qu1nt }
program Project1;

{$APPTYPE CONSOLE}

uses
  Windows, SysUtils, Classes, Contnrs, Math;

type
  TFile = class
    constructor Create(const Name: AnsiString; Size: Int64; Time: Integer);
  private
    Name: AnsiString;
    Size: Int64;
    Time: Integer;
  end;

  TFiles = class(TObjectList)
    constructor Create(const Path, Mask: AnsiString);
  public
    type
      TOrder = (ORDER_ASC, ORDER_DESC);
      TSort  = (SORT_NAME, SORT_SIZE, SORT_DATE);
    procedure Print(const SortFlags: array of TSort;
      OrderType: TOrder = ORDER_ASC; List: TStrings = nil);
  private
    class var
      SortFlags : array of TSort;
      Order : TOrder;
  end;

function EpicSort(Item1, Item2: Pointer): Integer;
var
  SortFlag: TFiles.TSort;
begin
  Result := 0;
  for SortFlag in TFiles.SortFlags do
  begin
    case SortFlag of
      SORT_NAME : Result := AnsiCompareStr(TFile(Item1).Name, TFile(Item2).Name);
      SORT_SIZE : Result := CompareValue(TFile(Item1).Size, TFile(Item2).Size);
      SORT_DATE : Result := CompareValue(TFile(Item1).Time, TFile(Item2).Time);
    end;
    // по убыванию? инвертируем результат
    if TFiles.Order = ORDER_DESC then
      Result := - Result;
    // если сравниваемые данные не равны
    if Result <> 0 then
      Exit;
  end;
end;

{ TFile }
constructor TFile.Create;
begin
  Self.Name := Name;
  Self.Size := Size;
  Self.Time := Time;
end;

{ TFiles }
constructor TFiles.Create;
var
  SearchRec: TSearchRec;
begin
  inherited Create;
  // ищем файлы по заданной маске, директории игнорируются
  if FindFirst(IncludeTrailingPathDelimiter(Path) + Mask,
    faAnyFile - faDirectory, SearchRec) = 0 then
  repeat
    // добавляем в список
    with SearchRec do
      Add(TFile.Create(Name, Size, Time));
  until FindNext(SearchRec) <> 0;
  FindClose(SearchRec);
end;

procedure TFiles.Print;

  function PrintLn(const Line: AnsiString): AnsiString;
  begin
    if Line <> '' then
    begin
      SetLength(Result, Length(Line));
      // корректный вывод русских букавок = )
      CharToOem(PAnsiChar(Line), PAnsiChar(Result));
    end;
    WriteLn(Result);
  end;

var
  Item: Pointer;
begin
  // если не указали ниодного типа сортировки - сортировать не будем
  SetLength(Self.SortFlags, Length(SortFlags));
  if Length(Self.SortFlags) > 0 then
  begin
    System.Move(SortFlags[0], Self.SortFlags[0], Length(SortFlags) * SizeOf(TSort));
    Self.Order := OrderType;
    // наша эпическая сортировка
    Sort(EpicSort);
  end;
  // если указан список - пишем в него
  // очистка списка, Begin-EndUpdate на Ваших плечах :)
  for Item in Self do
    with TFile(Item) do
      if Assigned(List) then
        List.Append(Name)
      else
        PrintLn(Name);
end;

begin
  // получаем список файлов только один раз - в конструкторе
  with TFiles.Create('c:\', '*.*') do
    try
      // указываем тип, порядок сортировки и выходной список
      // сортировки: SORT_NAME, SORT_SIZE, SORT_DATE - по имени, размеру, дате
      // порядок: ORDER_ASC, ORDER_DESC - по возрастанию, убыванию
      //
      // можно сортировать сразу по нескольким параметрам
      // например, нижеприведенный пример будет сперва сравнивать размеры
      // двух файлов. Если они одинаковы - дополнительно сравнит их имена
      Print([SORT_SIZE, SORT_NAME], ORDER_DESC);
      // Print([SORT_DATE, SORT_SIZE, SORT_NAME]); ORDER_ASC - по-умолчанию
      // Print([]); - без сортировки
      // Print([SORT_NAME], ORDER_ASC, List); - запись в список
    finally
      // освобождаем память
      Free;
    end;
  ReadLn;
end.


Это сообщение отредактировал(а) Qu1nt - 30.10.2009, 14:46
PM MAIL   Вверх
Beltar
Дата 29.10.2009, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 3
Всего: 7



Цитата

 небольшой пример можно?


Примерно за 50 минут, включая время на поиск мегадурацкой ошибки мой мозг родил вот это. Только компонент из архива сначала установи.

Присоединённый файл ( Кол-во скачиваний: 19 )
Присоединённый файл  FileScaner.rar 30,02 Kb


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
Keeper89
Дата 29.10.2009, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



Qu1nt, 
Beltar, 
спасибо посмотрю.

Qu1nt, что означает процедура PrintLn, которая "должна работать"? smile


--------------------
PM MAIL WWW   Вверх
Qu1nt
Дата 29.10.2009, 22:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 13.1.2007

Репутация: 18
Всего: 50



Корректный вывод русских букавок в консоль = )
PM MAIL   Вверх
Keeper89
Дата 29.10.2009, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



Я так и подумал, спс, пример отличный, пока поразбираюсь в нем.

Это сообщение отредактировал(а) Keeper89 - 29.10.2009, 22:18


--------------------
PM MAIL WWW   Вверх
Qu1nt
Дата 30.10.2009, 00:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 13.1.2007

Репутация: 18
Всего: 50



Оптимизировал пример, обновил пост.
PM MAIL   Вверх
Qu1nt
Дата 30.10.2009, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 13.1.2007

Репутация: 18
Всего: 50



Добавил возможность сортировки по нескольким параметрам. 
PM MAIL   Вверх
Keeper89
Дата 31.10.2009, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 20
Всего: 58



А в чем заключалась оптимизация?


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0633 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.