在PHP中将文本文件转换为多维关联数组

时间:2014-09-02 03:45:41

标签: php arrays multidimensional-array associative-array

我有这个实验室问题,我现在已经被困了三天了,我非常肯定经过无数的谷歌搜索并尝试了几乎所有我能找到的东西,我只是把自己弄得一塌糊涂丢失。我不确定这是不是你们这样做的,但基本上我想要的答案是“如何”到达那里。在我的脑海中,我知道自己想做什么,但却无法深入了解代码。

首先,我有一个文本文件postcode.txt,其中包含一个邮政编码列表及其各自的郊区,如下所示:

3000,MELBOURNE
3001,MELBOURNE
3002,EAST MELBOURNE
3003,WEST MELBOURNE

这需要放入一个数组,其中郊区名称为键,邮政编码为值。如您所见,一些郊区有多个邮政编码。我认为这将是一个多维关联数组吗?

我不确定是否最好使用file()或file_get_contents(),因为我是PHP的新手,以前从未使用过数组,更不用说令人困惑的事了。 然后我可以假设我需要用','来爆炸文本行,并以某种方式将郊区作为键,将邮政编码作为值。

一旦这是一个数组,我需要通过用户输入搜索特定郊区名称的数组,并且需要返回该郊区的值。从我尝试的事情来看,它根本不会返回值,所以我只能假设它与区分大小写或空格等有关。

当我还没有处理简单数组的任何实验问题时,我不完全确定为什么这是一个实验室问题,但除了拼命尝试理解这一点之外我无能为力。这让我很生气。 非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

阅读文件

首先,打开文件... file()是将文件读入数组的最简单方法,因为它是用一行执行的。

<强>缺点:

  • file()对于较大的文件来说可能会很慢,因为它需要先将整个文件读入数组才能使用它

或者,使用fgets()之类的标准文件打开结构来逐行读取。

<强>缺点:

  • 需要更多代码行

让我们以file()为例:

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

获取数组结构

问题的第一部分是如何获得所需的数组结构,即郊区名称作为数组键,所有后置代码作为值。有很多方法可以做到这一点 - 这是一个使用foreach的简单示例:

// Define an empty array to start with
$postcodes = array();
// Loop each line
foreach($lines as $line) {
    // Split the line by the comma and define the variables with each part
    // mapping trim to the array to remove any whitespace on either end
    list($postcode, $suburb) = array_map('trim', explode(',', $line));
    // Check the array key exists in post codes
    if(!array_key_exists($suburb, $postcodes)) {
        // If not, define it to start with
        $postcodes[$suburb] = array();
    }

    // Check if the postcode is already in the array
    if(in_array($postcode, $postcodes[$suburb])) {
        // Skip this postcode, it's already where it should be
        continue;
    }

    // Add the postcode to it
    $postcodes[$suburb][] = $postcode;
}

文档: array_map()array_key_exists()in_array()explode()foreachcontinue

结果数组的输出将产生如下结果:

Array
(
    [MELBOURNE] => Array
        (
            [0] => 3000
            [1] => 3001
        )

    [EAST MELBOURNE] => Array
        (
            [0] => 3002
        )

    [WEST MELBOURNE] => Array
        (
            [0] => 3003
        )

)

搜索数组

搜索是一壶鱼,有很多事情需要考虑。是否要返回区分大小写的结果,不区分大小写,部分结果,多个结果等?

以下是一些选项以及您应该使用的选项:

  • 完全匹配(单曲):array_keys($postcodes, 'suburb name')
  • 完全匹配(多个):当你使用数组键时(根据定义是唯一的),不会发生这种情况。
  • 部分匹配(单个):匹配键和搜索词的循环,strstr()(区分大小写)或stristr()(不区分大小写),如果找到则终止循环
  • 部分匹配(多个):与上述相同,但如果发现了该循环,则不要删除循环,而是添加到匹配结果的数组并返回

这是一个示例函数,用于返回数组中所有部分匹配的结果:

function search($postcodes, $search_term) {
    // Define empty array for matches
    $matches = array();
    // Trim the search string to remove whitespace from either end
    $search_term = trim($search_term);
    // Loop through postcodes
    foreach($postcodes as $suburb => $post_codes) {
        // Case insensitive comparison
        if(stristr($suburb, $search_term)) {
            // It matches! Add entire result to return array
            $matches[$suburb] = $post_codes;
        }
    }
    // Return result
    return $matches; 
}

使用示例:

print_r($search($postcodes, 'melbourne'));
print_r($search($postcodes, 'east'));

Array
(
    [MELBOURNE] => Array
        (
            [0] => 3000
            [1] => 3001
        )

    [EAST MELBOURNE] => Array
        (
            [0] => 3002
        )

    [WEST MELBOURNE] => Array
        (
            [0] => 3003
        )

)
Array
(
    [EAST MELBOURNE] => Array
        (
            [0] => 3002
        )

)

展望未来,您可能还希望将作为字符串传入的任何搜索字词匹配,例如&#34;东西&#34;匹配墨尔本东部和西部。在这种情况下,您需要将搜索字符串分解为空格,并对每个字词执行搜索。您需要确保此处仅返回唯一值。这是一个能够做到这一点的函数的例子:

function search_multi($postcodes, $search_term) {
    // Define empty array for matches
    $matches = array();
    // Trim the search string
    $search_term = trim($search_term);
    // Get all search terms
    $search_terms = explode(' ', $search_term);
    // Loop through search terms
    foreach($search_terms as $term) {
        // Loop through postcodes
        foreach($postcodes as $suburb => $post_codes) {
            // First, check that this result hasn't already been found! (unique)
            if(array_key_exists($suburb, $matches)) {
                // It's already been found, skip this one...
                continue;
            }
            // Case insensitive comparison
            if(stristr($suburb, $term)) {
                // It matches! Add entire result to return array
                $matches[$suburb] = $post_codes;
            }
        }    
    }
    // Return result
    return $matches; 
}

如果您搜索&#34;东西&#34;,结果将是:

Array
(
    [EAST MELBOURNE] => Array
        (
            [0] => 3002
        )

    [WEST MELBOURNE] => Array
        (
            [0] => 3003
        )

)

结论

如果这种数据结构不止一次被使用,那么这种数据结构最好存储在数据库中,但要解析文本/ CSV文件,这就是你接近它的方式。希望这会有所帮助。