简体   繁体   English

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

[英]Converting text file into multi-dimensional associative array in PHP

I have this lab problem that I've now been stuck on for three days and I'm pretty sure after countless googling and trying pretty much everything I can find, that I've just confused myself to the point of being utterly lost. 我遇到了这个实验室问题,现在已经坚持了三天,并且可以肯定的是,经过无数次谷歌搜索和尝试了几乎所有可以找到的一切之后,我确信自己已经迷失了自己,完全迷失了自己。 I'm not sure if this is what you guys do, but essentially I want the answer with a "how to" of how you got there. 我不确定这是否是你们的工作,但从本质上讲,我希望答案是“如何”到达那里的。 In my head I know what I want to do but just cannot fathom getting this into code. 在我的脑海里,我知道我想做什么,但无法理解将其纳入代码中。

To start, I have a text file, postcode.txt, with a list of postcodes and their respective suburbs like so: 首先,我有一个文本文件postcode.txt,其中包含邮政编码列表及其各自的郊区,如下所示:

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

This needs to be put into an array with the suburb names as the keys, and the postcodes as the values. 这需要放入一个以郊区名称为键,以邮政编码为值的数组。 As you can see, some suburbs have more than one postcode. 如您所见,有些郊区有多个邮政编码。 Am I correct in thinking this will be a multi-dimensional associative array? 我认为这将是一个多维关联数组,对吗?

I'm not sure if it's best to use file() or file_get_contents() as I'm very new to PHP and have never even used an array before, let alone something this confusing. 我不确定是否最好使用file()或file_get_contents(),因为我对PHP还是很陌生,甚至从未使用过数组,更不用说这令人困惑了。 I can then assume I need to explode the lines of text by ',' and somehow have the suburbs as keys and the postcodes as values. 然后,我可以假设我需要用','分隔文本行,并以某种方式将郊区作为键,将邮政编码作为值。

Once this is in an array I need to search this array by way of user input for a particular suburb name and it needs to return the value or values of that suburb. 将其放入数组后,我需要通过用户输入在该数组中搜索特定的郊区名称,并且它需要返回该郊区的一个或多个值。 From the things that I have tried it isn't returning values at all so I can only assume it's something to do with case sensitivity or white spaces etc. 从我尝试过的东西来看,它根本没有返回任何值,因此我只能认为这与区分大小写或空格等有关。

I'm not entirely sure why this is a lab question when I've yet to have any lab questions dealing with simple arrays, but nothing I can do except desperately try and understand this. 当我还没有处理简单数组的任何实验室问题时,我不能完全确定为什么这是一个实验室问题,但是我无能为力,除非拼命尝试理解这一点。 It's been driving me mad. 这让我发疯了。 Any help is very much appreciated. 很感谢任何形式的帮助。

Reading your file 读取文件

To start with, opening the file... file() is the easiest method to read a file into an array as it is performed with one line. 首先,打开文件... file()是将文件读入数组的最简单方法,因为它只用一行执行。

Drawbacks: 缺点:

  • file() can be slow for larger files, as it needs to read the entire file into an array before you can use it 对于较大的文件, file()可能会变慢,因为在使用它之前,它需要将整个文件读入数组

Alternatively, use the standard file open structure using something like fgets() to read it line by line. 或者,使用标准文件打开结构fgets()fgets()逐行读取它。

Drawbacks: 缺点:

  • more lines of code required 需要更多代码行

Let's use file() as an example: 让我们以file()为例:

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

Getting the array structure 获取数组结构

The first part of your question is how to get the array structure you want, which is the suburb name as the array key and all the post codes as the values. 问题的第一部分是如何获取所需的数组结构,以郊区名称作为数组键,将所有邮政编码作为值。 There are plenty of ways to do this - here's a simple example using a foreach: 有很多方法可以做到这一点-这是一个使用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;
}

Docs: array_map() , array_key_exists() , in_array() , explode() , foreach , continue 文件: array_map()array_key_exists()in_array()explode()foreachcontinue

An output of the resulting array would yield something like this: 结果数组的输出将产生如下内容:

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

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

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

)

Searching the array 搜索数组

Searching is a kettle of fish, and there are many things to consider. 搜索是一锅鱼,有很多事情要考虑。 Do you want to return a case sensitive result, case insensitive, partial results, multiple results etc? 您是否要返回区分大小写的结果,不区分大小写的结果,部分结果,多个结果等?

Here are some options and what you should use for them: 以下是一些选项以及应使用的选项:

  • Exact match (single): array_keys($postcodes, 'suburb name') 完全匹配(单个): array_keys($postcodes, 'suburb name')
  • Exact match (multiple): wouldn't happen as you're using array keys (unique by definition) 完全匹配(多个):使用数组键时不会发生(按定义唯一)
  • Partial match (single): a loop, strstr() (case sensitive) or stristr() (case insensitive) matching the key and the search term and killing the loop if it is found 部分匹配(单个):循环,匹配stristr()和搜索词的strstr() (区分大小写)或stristr() (不区分大小写),如果找到则终止循环
  • Partial match (multiple): same as above, but don't kill the loop if it's found, instead add to an array of matched results and return that 部分匹配(多个):与上面相同,但不要杀死找到的循环,而要添加到匹配结果数组中并返回

Here's an example function to return all partially matches results from the array: 这是一个示例函数,用于返回数组中所有部分匹配的结果:

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; 
}

Example use: 使用示例:

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
        )

)

Looking forward, you might also want to match any of the search terms passed in as a string, eg "east west" to match both east and west Melbourne. 展望未来,您可能还想匹配以字符串形式传递的任何搜索词,例如“ east west”以匹配墨尔本的东西方。 In this case you'll need to explode the search string to spaces, and perform a search on each term. 在这种情况下,您需要将搜索字符串分解为空格,然后对每个术语进行搜索。 You'll need to ensure to only return unique values here. 您需要确保此处仅返回唯一值。 Here's an example of a function that would do that: 这是一个可以做到这一点的函数的例子:

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; 
}

And given you search for "east west", the result would be: 并给您搜索“东西”,结果将是:

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

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

)

Conclusion 结论

This kind of data structure would be best to be stored in a database if it's going to be used more than once, but to parse a text/CSV file this is how you'd approach it. 如果要多次使用这种数据结构,最好将其存储在数据库中,但是要解析文本/ CSV文件,这就是您要采用的方法。 Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM