Автор Тема: _FileDeleteDuplicateLines - Удаление дубликатов в файле  (Прочитано 5569 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7827
  • Репутация: 2288
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
AutoIt: 3.3.8.1
Версия: 1.0

Категория: Строки, Данные, Файловая система

Описание: Удаление дублирующихся строк в файле.

Код/Пример:
(нажмите для показа/скрытия)

Функция:
(нажмите для показа/скрытия)

История версий:
(нажмите для показа/скрытия)

Источник: autoit-script.ru
Автор(ы): G.Sandler (CreatoR)
« Последнее редактирование: Декабрь 04, 2012, 03:17:55 от CreatoR »


Правила, Поиск, Супер тема


AutoIt is simple, subtle, elegant.


«Не оказываю тех. поддержку через ПМ/ICQ, и по электронной почте - для этого есть форум. (C)»
«Законы Мэрфи неоспоримы!»


Мои работы

Русское сообщество AutoIt

_FileDeleteDuplicateLines - Удаление дубликатов в файле
« Отправлен: Декабрь 03, 2012, 14:48:24 »

Оффлайн madmasles [?]

  • Глобальный модератор
  • *
  • Сообщений: 7790
  • Репутация: 2317
  • Пол: Мужской
  • Награды За модерирование форума
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: _FileDeleteDuplicateLines - Удаление дубликатов в файле
« Ответ #1, Отправлен: Декабрь 03, 2012, 15:41:17 »
CreatoR,
А Вы это не забыли?
Код: AutoIt [Выделить]
$oDictionary.CompareMode


Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7827

  • Автор темы
  • Репутация: 2288
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: _FileDeleteDuplicateLines - Удаление дубликатов в файле
« Ответ #2, Отправлен: Декабрь 03, 2012, 17:09:29 »
madmasles  [?]
Цитировать
А Вы это не забыли?
Забыл :whistle: .

Спасибо, обновил (версия не изменилась).

Оффлайн AZJIO [?]

  • VIP
  • *
  • Сообщений: 2725
  • Репутация: 1140
    • мой сайт
    • Награды
  • Версия AutoIt: 3.3.8.1
Re: _FileDeleteDuplicateLines - Удаление дубликатов в файле
« Ответ #3, Отправлен: Декабрь 04, 2012, 01:43:39 »
Уточнение  ;)
_FileDeleteDuplicateLines - Удаление дубликатов строк в файле

Русское сообщество AutoIt

Re: _FileDeleteDuplicateLines - Удаление дубликатов в файле
« Ответ #3 Отправлен: Декабрь 04, 2012, 01:43:39 »

Оффлайн WSWR [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 939
  • Репутация: 353
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: _FileDeleteDuplicateLines - Удаление дубликатов в файле
« Ответ #4, Отправлен: Декабрь 04, 2012, 14:05:44 »
CreatoR
Интересно, а можно на таком принципе написать пример, показывающий количество каждой из уникальных строк в исходном файле? Вроде словаря?

Оффлайн AZJIO [?]

  • VIP
  • *
  • Сообщений: 2725
  • Репутация: 1140
    • мой сайт
    • Награды
  • Версия AutoIt: 3.3.8.1
Re: _FileDeleteDuplicateLines - Удаление дубликатов в файле
« Ответ #5, Отправлен: Декабрь 13, 2012, 04:01:33 »
В UDF RESH удаление дубликатов проще, вызов просто не добавляет новый ключ, если он уже существует.
Код: AutoIt [Выделить]
Func _ArrayRemoveDuplicates(Const ByRef $aArray)
    If Not IsArray($aArray) Then Return SetError(1, 0, 0)
    Local $oSD = ObjCreate("Scripting.Dictionary")
    For $i In $aArray
        $oSD.Item($i) ; shown by wraithdu
    Next
    Return $oSD.Keys()
EndFunc


Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7827

  • Автор темы
  • Репутация: 2288
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: _FileDeleteDuplicateLines - Удаление дубликатов в файле
« Ответ #6, Отправлен: Декабрь 13, 2012, 09:24:09 »
AZJIO  [?]
Цитировать
вызов просто не добавляет новый ключ, если он уже существует
Так при удалении строк нужно строить строковую переменную, иначе придётся запускать ещё один цикл для записи. Т.ч проверка нужна в этом случае.

Оффлайн AZJIO [?]

  • VIP
  • *
  • Сообщений: 2725
  • Репутация: 1140
    • мой сайт
    • Награды
  • Версия AutoIt: 3.3.8.1
Re: _FileDeleteDuplicateLines - Удаление дубликатов в файле
« Ответ #7, Отправлен: Декабрь 14, 2012, 01:16:55 »
CreatoR
Я проверил скорость на 3000 IP-шнеков и твой вариант с Exists оказался действительно быстрей в разы, именно за счёт несоздания второго цикла и вызова Keys(). А если использовать вывод массивом, то проигрывает на ~5%.

Вот тестовый пример
(нажмите для показа/скрытия)

Ещё вопрос, почему функция сделана имено по работе с файлом? То есть заложено 2 операции, хотя открыть файл для многих не проблема. В таком случае лучше иметь составные функции, одна открывает/закрывает файл, а между ними вызов функции обработки данных, чтобы функцию обработки данных можно было использовать самостоятельно.

Русское сообщество AutoIt

Re: _FileDeleteDuplicateLines - Удаление дубликатов в файле
« Ответ #7 Отправлен: Декабрь 14, 2012, 01:16:55 »

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7827

  • Автор темы
  • Репутация: 2288
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Re: _FileDeleteDuplicateLines - Удаление дубликатов в файле
« Ответ #8, Отправлен: Декабрь 14, 2012, 03:18:11 »
AZJIO  [?]
Цитировать
почему функция сделана имено по работе с файлом?
Потому что у меня ещё с давних времён валялась эта функция, и работала очень медленно :).

Цитировать
заложено 2 операции, хотя открыть файл для многих не проблема
Не проблема, но в любом случае для записи в файл и чтения с него, придётся перебирать цикл (если использовать удаление в массиве), а это опять же замедление.

Оффлайн AZJIO [?]

  • VIP
  • *
  • Сообщений: 2725
  • Репутация: 1140
    • мой сайт
    • Награды
  • Версия AutoIt: 3.3.8.1
Re: _FileDeleteDuplicateLines - Удаление дубликатов в файле
« Ответ #9, Отправлен: Декабрь 14, 2012, 03:50:58 »
CreatoR  [?]
Цитировать
а это опять же замедление.
Почему замедление? Принцип такой:
Код: AutoIt [Выделить]
Func _FileDeleteDuplicateLines(...)
    FileRead(...)
    $result = _DeleteDuplicateLines(...)
    FileWrite($result)
EndFunc

Func _DeleteDuplicateLines(...)
    ...
EndFunc


Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7827

  • Автор темы
  • Репутация: 2288
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
AZJIO  [?]
Цитировать
Принцип такой
А что будет передаваться функциям, массив или строка?
В первом варианте (а исходя из замысла, оно так и есть) замедление неизбежно. Массив нужно построить (прочитав с файла), а потом собрать (для записи в файл).

Оффлайн AZJIO [?]

  • VIP
  • *
  • Сообщений: 2725
  • Репутация: 1140
    • мой сайт
    • Награды
  • Версия AutoIt: 3.3.8.1
CreatoR  [?]
Цитировать
А что будет передаваться функциям, массив или строка?
Строка, то есть замедление будет только на вызов функции, а это ничтожное замедление по сравнению с обработкой данных, а тем более записью на HDD.

На счёт возможности передачи массива, то есть усложнения функции, это конечно можно реализовать но мои попытки превращали функцию в сложно-запутанное, поэтому советовать не буду.

Вот пример запутанной функции, которую в итоге почти нигде не использую
Код: AutoIt [Выделить]
; ===============================================================================================================================
; Описание ...: Поиск и удаление дубликатов в данных
; Синтаксис.........: _ArrayUnique2($data[, $flag=-1])
; Параметр1....: $data - данные, массив или строка с разделителем
; Параметр2 ....: $flag
;                           Если массив, то $flag является индексом массива от которого производить поиск
;                           Если строка, то $flag является разделителем, по умолчанию "|"
; Возвращает .: Успешно        - массив без дубликатов
;                           Ошибка    - 0 и @error=1
; Автор ........: AZJIO
; Remarks .......: В данных не должно быть символа "[", такие данные исключаются из массива, даже
;                       если не являются дубликатами, остальные спец-символы и буквы не вызывают ошибки
; ===============================================================================================================================
Func _ArrayUnique2($data, $flag = -1)
    Local $k, $i, $tmp
    Assign('/', 1, 1) ;для исключения пустых строк и не совпадения с локальными переменными
    If IsArray($data) Then
        If $flag = -1 Then $flag = 0
        $tmp = UBound($data) - 1
        If $flag > $tmp Then Return SetError(1, 0, 0)
        $k = 0
        For $i = $flag To $tmp
            Assign($data[$i] & '/', Eval($data[$i] & '/') + 1, 1)
            If Eval($data[$i] & '/') = 1 Then
                $data[$k] = $data[$i]
                $k += 1
            EndIf
        Next
        If $k = 0 Then Return SetError(1, 0, 0)
        ReDim $data[$k]
        Return $data
    Else
        If $flag = -1 Then $flag = '|'
        $data = StringSplit($data, $flag)
        If Not @error Then
            $k = 0
            For $i = 1 To $data[0]
                Assign($data[$i] & '/', Eval($data[$i] & '/') + 1, 1)
                If Eval($data[$i] & '/') = 1 Then
                    $data[$k] = $data[$i]
                    $k += 1
                EndIf
            Next
            If $k = 0 Then Return SetError(1, 0, 0)
            ReDim $data[$k]
            Return $data
        Else
            Return SetError(1, 0, 0)
        EndIf
    EndIf
EndFunc   ;==>_ArrayUnique2


Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7827

  • Автор темы
  • Репутация: 2288
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
AZJIO
Я не совсем понимаю что ты предлагаешь.

Функция в данной теме предназначена для файлов, для строк и массивов можно сделать другую, с другим алгоритмом.
Не вижу в чём проблема.

Оффлайн nowost [?]

  • Новичок
  • *
  • Сообщений: 178
  • Репутация: 17
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
CreatoR , пробую обработать файл большого размера вашей функцией, 200мб примерно, в режиме словаря работает очень шустро. Есть только одно но, примерно на 95% обработки съедается примерно 3.5 Гига памяти и происходит вылет с ошибкой, что недостаточно памяти(  Я так понимаю нужно исходный файл разбивать на более мелкие куски и с ними работать ? или возможно както оптимизировать вашу функцию ?

Русское сообщество AutoIt

Re: _FileDeleteDuplicateLines - Удаление дубликатов в файле
« Ответ #13 Отправлен: Июнь 05, 2018, 10:42:10 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
5 Ответов
5895 Просмотров
Последний ответ Июль 02, 2011, 22:14:54
от CreatoR
5 Ответов
4320 Просмотров
Последний ответ Октябрь 29, 2012, 22:08:19
от gregaz
8 Ответов
3196 Просмотров
Последний ответ Март 15, 2013, 16:32:47
от gregaz
4 Ответов
4786 Просмотров
Последний ответ Июнь 11, 2013, 23:04:48
от madmasles
5 Ответов
3546 Просмотров
Последний ответ Июнь 18, 2013, 04:05:50
от Andrey_A
4 Ответов
1726 Просмотров
Последний ответ Сентябрь 06, 2014, 15:27:46
от wisenlucky
12 Ответов
2855 Просмотров
Последний ответ Октябрь 24, 2017, 04:20:24
от dr.room
2 Ответов
1965 Просмотров
Последний ответ Апрель 15, 2017, 19:03:06
от Garrett
3 Ответов
2470 Просмотров
Последний ответ Июнь 28, 2017, 17:00:31
от Garrett
6 Ответов
475 Просмотров
Последний ответ Май 03, 2018, 22:44:06
от seriousstas