簡體   English   中英

從一維數組創建關聯數組

[英]Creating an associative array from one-dimension array

不確定在什么標題下找到標題...

范例.csv

tennis,soccer,sports
car,plane,things
jeans,shirt,things

我最終的理想結果應該是一個看起來像這樣的數組:

Array
(
    [sports] => Array
        (
            [0] => tennis
            [1] => soccer
        )

    [things] => Array
        (
            [0] => car
            [1] => plane
            [2] => jeans
            [3] => shirt
        )

)

這是我最近達到上述結果的嘗試(經過多次嘗試):

<?php
$f_name = 'test.csv';
// Stores all csv data
$csv_data = array_map('str_getcsv', file($f_name));
$c = count($csv_data);

$tmp = array();
$data_for_email = array();

for ($i = 0; $i < $c; $i++) {
    // Remove last element and make it a key
    $le = array_pop($csv_data[$i]);
    $tmp[$le] = $csv_data[$i];
    $data_for_email = array_merge_recursive($data_for_email, $tmp); // MEMORY ERROR
}

print_r($data_for_email);
?>

這就是我得到的結果:

Array
(
    [sports] => Array
        (
            [0] => tennis
            [1] => soccer
            [2] => tennis
            [3] => soccer
            [4] => tennis
            [5] => soccer
        )

    [things] => Array
        (
            [0] => car
            [1] => plane
            [2] => jeans
            [3] => shirt
        )

)

如您所見,我在[sports]數組中得到了.csv第1行的副本。

我的要求的詳細說明:

  1. 每行有3個字段。
  2. 第三字段成為新關聯數組中的key
  3. 剩下的兩個字段(第1個和第2個)成為該key values
  4. 因為多行可能(並且確實)包含相同的第三字段(而第一字段和第二字段的組合始終不同),所以我需要將所有這些重復鍵的值合並為1。

PS我以后可以解析該數組(以刪除重復的值),但是真正的.csv文件很大,處理它變得太慢,並且在用// MEMORY ERROR標記的行上收到以下錯誤:

致命錯誤:允許的134217728字節的內存大小已用盡

我嘗試增加內存限制,但如果可能的話,我寧願避免這種情況。

應該會容易一些。 不需要array_merge_recursive

foreach($csv_data as $row) {
    $key = array_pop($row);
    if(!isset($data_for_email[$key])) {
        $data_for_email[$key] = [];
    }
    $data_for_email[$key] = array_merge($data_for_email[$key], $row);
}

更高的內存效率將是:

  1. 無法讀取內存中的整個文件。 fgetcsv讀取一行
  2. 避免遞歸合並

碼:

$handle = fopen($f_name, 'r');
if (!$handle) { 
    // Your error-handling
    die("Couldn't open file");
}

$data_for_email = array();
while($csvLine = fgetcsv($handle)) {
    // Remove last element and make it a key
    $le = array_pop($csvLine);
    if (isset($data_for_email[$le])) {
        $data_for_email[$le] = array_merge($data_for_email[$le], $csvLine);
    } else {
        $data_for_email[$le] = $csvLine;
    }
}

fclose($handle);

您只需要在每個循環中初始化$tmp解決您的問題。 檢查以下代碼:

for ($i = 0; $i < $c; $i++) {
    // Remove last element and make it a key
    $le = array_pop($csv_data[$i]);
    $tmp = []; //Reset here
    $tmp[$le] = $csv_data[$i];
    $data_for_email = array_merge_recursive($data_for_email, $tmp); // MEMORY ERROR
}

希望對您有幫助。

使用名稱作為密鑰以獲得唯一列表。 如果有大量數據,它比合並便宜。

$handle = fopen('test.csv', 'r');
$res = [];

while ($data = fgetcsv($handle)) {
    list($first, $second, $type) = $data;
    $res[$type] = ($res[$type] ?? []);

    array_map(function($e)use(&$res, $type) {
        $res[$type][$e] = $e;
    }, [$first, $second]);
}

輸出:

Array
        (
            [sports] => Array
                (
                    [tennis] => tennis
                    [soccer] => soccer
                )

            [things] => Array
                (
                    [car] => car
                    [plane] => plane
                    [jeans] => jeans
                    [shirt] => shirt
                )

        )

我也做了一些,但是現在其他的都快了。 :D我已經做到了,它並沒有完全滿足您的要求,但也許可以幫助您進一步。

不幸的是,我現在還沒有進一步想向您展示:)

這是您的index.php(或任何稱為文件的文件。)

<?php
include "Data.php";

$f_name = 'in.csv';
// Stores all csv data
$csv_data = array_map('str_getcsv', file($f_name));
$c = count($csv_data);

$tmp = array();
$data_for_email = array();

foreach ($csv_data as $data){
    $key = array_pop($data);
    array_push($data_for_email,new Data($data,$key));
}
foreach ($data_for_email as $data){
    array_push($tmp,$data->getValue());
}

foreach ($tmp as $value){
    print_r($value);
    echo "<br>";
}

這里是類數據:

<?php


class Data
{
    private $value = [];

    public function __construct($data, $key)
    {
        $this->value[$key]=$data;
    }

    /**
     * @return array
     */
    public function getValue()
    {
        return $this->value;
    }
}

作為輸出,您將得到如下所示的內容:

Array ( [sports] => Array ( [0] => tennis [1] => soccer ) ) 
Array ( [things] => Array ( [0] => car [1] => plane ) ) 
Array ( [things] => Array ( [0] => jeans [1] => shirt ) ) 

ps:當然還有另一個功能可以總結相同的鍵,但是不知何故我現在什么也沒找到...希望對您有幫助:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM