2012-01-16 31 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

顯示到目前爲止,你已經嘗試的代碼,我們會盡力幫助解決問題。但是你必須展示一些努力 - 我們不會爲你寫。這不是這個網站的工作原理。 – 2012-01-16 04:22:43

回答

1

這裏是我採取在此:

  1. 使用file讀取數據文件,產生其中每個元素對應於輸入的線的陣列。
  2. 使用array_filtertrim作爲過濾器函數,以從該陣列中刪除空行。這有利於trim返回一個字符串,該字符串從其參數的兩端刪除了空白,如果參數全部爲空白,則保留空字符串。 The empty string converts to boolean false - 因此使array_filter忽略全部爲空白的行。
  3. 使用array_map與涉及到調用explode到每個數組元素(文本行)分成三個部分,並且在返回的這些第二回調。這將產生一個數組,其中每個元素只是一個名稱。
  4. 使用array_map再次strtoupper作爲回調的所有名稱轉換爲大寫,使「吉姆」和「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 2012-01-16 17:58:00

2

使用分隔符(在本例中爲||)在每行中讀取explode,並將其添加到數組(如果它不存在)。如果是這樣,請增加計數。

我不會寫代碼的你,但這裏有幾個指針:

fread在一條線上

explode將分裂基礎上的分隔符

使用in_array線檢查讀取如果之前已經找到該名稱,並確定是否需要將名稱添加到數組中或者只是增加計數。

編輯:

繼Jon的建議,你可以把它的程序更簡單。

逐行讀取,按分隔符分解並將所有名稱轉儲到數組中(不必擔心檢查它是否已存在)。完成後,請使用array_count_values獲取每個唯一的名稱及其頻率。

+1

其實,如果你「不知何故」項目爲名稱的數組有同樣['array_count_values'(http://php.net/manual/en/function.array-count-values.php)可用。 – Jon 2012-01-16 04:25:35

+0

@Jon:太棒了!這幾乎爲他解決了這個問題。 PHP在構建函數中有些非常有用 – xbonez 2012-01-16 04:27:51

+0

是的,有足夠的函數可以將它寫成單行數據。 – Jon 2012-01-16 04:29:20

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 2012-01-16 04:37:35

+0

爲什麼在['file_get_contents'](http://www.php.net/manual/en/function.file-get-contents.php)可用時進行'fopen'儀式?當['file'](http://www.php.net/manual/en/function.file.php)時,爲什麼讀取內容然後在換行符上爆炸? – Jon 2012-01-16 04:50:51

+0

@喬恩:同時的file_get_contents是不錯的,我個人覺得它來介紹一點至關重要['fopen'(http://php.net/fopen),['fread'](http://php.net/fread )和['fclose'](http://php.net/fclose),因爲它們在其他編程語言中被廣泛使用。 (還要注意'$ pointer'變量;-)) – 2012-01-16 04:56:44