Как я могу удалить дубликаты строк в файле с помощью PHP (включая «оригинальную»)?

Ну, мой вопрос очень прост, но я нигде не нашел правильного ответа. Что мне нужно, так это найти способ, который читает файл .txt, и, если есть дублирующаяся строка, удалите ВСЕ из них, не сохраняя ни одного. Например, в .txt содержится следующее:

1234
1233
1232
1234

Выход должен быть:

1233
1232

Поскольку код должен удалить дублированную строку, все из них. Я искал всю сеть, но он всегда указывает на ответы, которые удаляют дублированные строки, но сохраняют одну из них, например этот, этот или же тот.

Я боюсь, что единственный способ сделать это — прочитать строку x и проверить весь .txt, если он найдет равный результат, удалить и удалить строку x тоже. Если нет, перейдите к следующей строке. Но файл .txt, который я проверяю, содержит 50 миллионов строк (~ 900 МБ), я не знаю, сколько памяти мне нужно для выполнения такого рода задач, поэтому я ценю некоторую помощь здесь.

0

Решение

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

$lines = array();
$fd = fopen("inputfile.txdt", "r");
while ($line = fgets($fd)) {
$line = rtrim($line, "\r\n"); // ignore the newline
if (array_key_exists($line, $lines)) {
$lines[$line]++;
} else {
$lines[$line] = 1;
}
}
fclose($fd);
$fd = fopen("outputfile.txt", "w");
foreach ($lines as $line => $count) {
if ($count == 1) {
fputs($fd, "$line" . PHP_EOL); // add the newlines back
}
}
3

Другие решения

Я сомневаюсь, что есть одна и только одна функция, которая делает все, что вы хотите сделать. Итак, это разбивает его на шаги …

Во-первых, можем ли мы загрузить файл непосредственно в массив? Смотрите документацию для file команда

$lines = file('mytextfile.txt');

Теперь у меня есть все строки в массиве. Я хочу посчитать, сколько у меня каждой записи. Смотрите документацию для array_count_values команда.

$counts = array_count_values($lines);

Теперь я могу легко перебрать массив и удалить любые записи, где количество> 1

foreach($counts as $value=>$cnt)
if($cnt>1)
unset($counts[$value]);

Теперь я могу превратить ключи массива (которые являются значениями) в массив.

$nondupes = array_keys($counts);

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

file_put_contents('myoutputfile.txt', $nondupes);
0

Я думаю, что у меня есть решение гораздо более элегантное:

$array = array('1', '1', '2', '2', '3', '4'); // array with some unique values, some not unique

$array_count_result = array_count_values($array); // count values occurences

$result = array_keys(array_filter($array_count_result, function ($value) { return ($value == 1); })); // filter and isolate only unique values

print_r($result);

дает:

Array
(
[0] => 3
[1] => 4
)
0
По вопросам рекламы [email protected]