如何使用PHP获取唯一名称?

时间:2012-01-16 04:20:41

标签: php

假设我的文本文件Data.txt包含:

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;
在爆炸||之后

,但它不起作用。 结果应该是: 吉姆-2, 蔡健雅-1, 等等。 谢谢你的帮助...

3 个答案:

答案 0 :(得分:2)

使用分隔符(在本例中为||)读取每一行explode,并将其添加到数组(如果它尚不存在)。如果是,请递增计数。

我不会为你编写代码,但这里有一些指示:

fread读一行

explode将根据分隔符

拆分该行

使用in_array检查之前是否找到了名称,并确定是否需要将名称添加到数组中或只是增加计数。

修改

根据Jon的建议,您可以更轻松地为您服务。

逐行读取,通过分隔符爆炸并将所有名称转储到数组中(不要担心检查它是否已存在)。完成后,使用array_count_values获取每个唯一名称及其频率。

答案 1 :(得分: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";
?>

答案 2 :(得分:1)

以下是我对此的看法:

  1. 使用file读取数据文件,生成一个数组,其中每个元素对应于输入中的一行。
  2. 使用array_filtertrim作为过滤器功能,从此阵列中删除空白行。这有利于trim返回一个字符串,该字符串从其参数的两端删除了空格,如果参数是以空格开头的所有空格,则保留空字符串。 The empty string converts to boolean false - 从而使array_filter忽略所有空格的行。
  3. array_map与回调一起使用,该回调涉及调用explode将每个数组元素(文本行)分成三部分并返回第二部分。这将生成一个数组,其中每个元素只是一个名称。
  4. 再次使用array_mapstrtoupper作为回调将所有名称转换为大写,以便“jim”和“JIM”在下一步中计算相同。
  5. 最后,使用array_count_values获取每个名称的出现次数。
  6. 代码,缓慢地处理事情:

    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

    我应该提一下,这可能不是解决问题的“最佳”方式,因为如果您的输入文件 large (在数百万行的大概中),这种方法将会消耗大量内存,因为它一次读取内存中的所有输入。然而,这当然很方便,除非你知道输入会那么大,否则就没有必要让生活变得更加艰难。

    注意:高级PHP开发人员可能已经注意到我通过将explode的结果提供给通过引用接受其参数的函数来违反严格标准。这是有效的批评,但在我的辩护中,我试图尽可能缩短代码。在生产中,使用$a = explode(...); return $a[1];确实会更好,尽管结果没有区别。