2012-01-16 1 views
-1

Скажем, у меня есть текстовый файл с data.txt:Как получить уникальный счет имени с помощью PHP?

26||jim||1990 
31||Tanya||1942 
19||Bruce||1612 
8||Jim||1994 
12||Brian||1988 
56||Susan||2201 

и продолжает идти.

У него много разных имен в столбце 2. Скажите, пожалуйста, как мне получить количество уникальных имен и сколько раз каждое имя появляется в файле с помощью PHP?

Я попытался:

$counts = array_count_values($item[1]); 
echo $counts; 

после взрыва ||, но он не работает. Результат должен быть примерно: jim-2, tanya-1, и так далее. Спасибо за любую помощь ...

+6

Покажите код, который вы попытались до сих пор, и мы постараемся его исправить. Но вам нужно показать НЕКОТОРЫЕ усилия - мы не будем писать это для вас. Это не то, как работает этот сайт. –

ответ

1

Вот мой взгляд на это:

  1. Использование file для чтения файла данных, создавая массив, где каждый элемент соответствует линии на входе.
  2. Используйте array_filter с trim как функцию фильтра, чтобы удалить пустые строки из этого массива. Это дает преимущество в том, что trim возвращает строку, удалив пробел с обоих концов ее аргумента, оставив пустую строку, если для начала был аргумент всех пробелов. The empty string converts to boolean false - таким образом, array_filter проигнорируйте строки, все пробелы.
  3. Используйте array_map с обратным вызовом, который включает вызов explode, чтобы разделить каждый элемент массива (строку текста) на три части и вернуть второй из них. Это создаст массив, в котором каждый элемент будет просто именем.
  4. Используйте array_map с strtoupper как обратный вызов для преобразования всех имен в верхний регистр, чтобы «jim» и «JIM» считались одинаковыми на следующем шаге.
  5. Наконец, используйте array_count_values, чтобы получить количество вхождений для каждого имени.

код, принимая вещи медленно:

function extract_name($line) { 
    // The -1 parameter (available as of PHP 5.1.0) makes explode return all elements 
    // but the last one. We want to do this so that the element we are interested in 
    // (the second) is actually the last in the returned array, enabling us to pull it 
    // out with end(). This might seem strange here, but see below. 
    $parts = explode('||', $line, -1); 
    return end($parts); 
} 

$lines = file('data.txt'); // #1 
$lines = array_filter($lines, 'trim'); // #2 
$names = array_map('extract_name', $lines); // #3 
$names = array_map('strtoupper', $names); // #4 
$counts = array_count_values($names); // #5 

print_r($counts); // to see the results 

Там причина, я решил сделать это в шагах, где каждый шаги включает в себя вызов функции на результат предыдущего шага - что это на самом деле возможно сделать это только в одной строке:

$counts = array_count_values(
      array_map(function($line){return strtoupper(end(explode('||', $line, -1)));}, 
      array_filter(file('data.txt'), 'trim'))); 

print_r($counts); 

See it in action.

Следует отметить, что это может быть не «лучший» способ решить проблему в том смысле, что если ваш входной файл огромный (на стадионе нескольких миллионов линий), этот подход будет потреблять много потому что он сразу считывает все данные в памяти. Тем не менее, это, безусловно, удобно и, если вы не знаете, что вход будет таким большим, нет смысла делать жизнь сложнее.

Примечание. Разработчики PHP на высшем уровне, возможно, заметили, что я нарушаю строгие стандарты здесь, подавая результат explode на функцию, которая принимает свой аргумент по ссылке. Это действительная критика, но в моей защите я стараюсь, чтобы код был как можно короче. В производстве было бы лучше использовать $a = explode(...); return $a[1];, хотя не будет никакой разницы в отношении результата.

+0

Большое вам спасибо за то, что нашли время, чтобы не только ответить мне и привести примеры, но и на самом деле что-то учить. Очень признателен. Позвольте мне попробовать и вернуться к вам ... – mobilestimulus

2

Прочитайте в каждой строке explode с использованием разделителя (в данном случае ||) и добавьте его в массив, если он еще не существует. Если это так, увеличьте счетчик.

Я не буду писать код для вас, но вот несколько советов:

fread читает в строке

explode расколется линия, основанная на разделителе

использование in_array проверить если имя было найдено ранее, и определить, нужно ли вам добавлять имя в массив или просто увеличивать счет.

Edit:

Следуя совету Джона, вы можете сделать это еще проще для вас.

Читайте в строке за строкой, взорвите разделителем и дамп всех имен в массив (не беспокойтесь о проверке, существует ли он уже). После того, как вы закончите, используйте array_count_values, чтобы получить каждое уникальное имя и его частоту.

+1

На самом деле, если вы «каким-то образом» проекта в массив имен, есть также ['array_count_values'] (http://php.net/manual/en/function.array-count-values.php). – Jon

+0

@Jon: Ницца! Это в значительной степени решает его для него. PHP был каким-то удивительно полезным в построенных функциях – xbonez

+0

Yup, есть достаточно функций, чтобы писать это как однострочный. – Jon

1

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

<?php 
$unique_name_count = 0; 
$names = array(); 

$filename = 'Data.txt'; 
$pointer = fopen($filename,'r'); 
$contents = fread($pointer,filesize($filename)); 
fclose($pointer); 

$lines = explode("\n",$contents); 

foreach($lines as $line) 
{ 
    $split_str = explode('|',$line); 
    if(isset($split_str[2])) 
    { 
     $name = strtolower($split_str[2]); 
     if(!in_array($name,$names)) 
     { 
      $names[] = $name; 
      $unique_name_count++; 
     } 
    } 
} 

echo $unique_name_count.' unique name'.(count($unique_name_count) == 1 ? '' : 's').' found in '.$filename."\n"; 
?> 
+0

Спасибо за пример кода. И для записи это не домашнее задание. Я попробую это и вернусь к вам здесь. Еще раз спасибо! – mobilestimulus

+0

Почему существует ритуал 'fopen', когда есть [' file_get_contents'] (http://www.php.net/manual/en/function.file-get-contents.php)? И зачем читать содержимое, затем взорваться на новой строке, когда есть ['файл'] (http://www.php.net/manual/en/function.file.php)? – Jon

+0

@Jon: while file_get_contents приятно, лично я чувствую, что очень важно представить ['fopen'] (http://php.net/fopen), [' fread'] (http://php.net/fread) и ['fclose'] (http://php.net/fclose), поскольку они широко используются среди других языков программирования. (также обратите внимание на переменную '$ pointer' ;-)) –

Смежные вопросы