为了账号安全,请及时绑定邮箱和手机立即绑定

从一维数组创建关联数组

从一维数组创建关联数组

PHP
饮歌长啸 2021-06-11 22:33:01
不太确定问题的标题应该在这里...示例 .csv:tennis,soccer,sportscar,plane,thingsjeans,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 行的重复项。我的要求的更详细描述:每行有 3 个字段。第三个字段成为key新关联数组中的 a。其余两个字段(第1次和第2次)成为values该key。因为多行可能(并且确实)包含相同的第三个字段(而第一个和第二个字段的组合总是不同的),所以我需要将所有这些重复键的值合并为 1。PS我之后可以解析该数组(以删除重复值),但真正的.csv文件很大并且处理它变得太慢,并且在我标记的行中收到以下错误// MEMORY ERROR:致命错误:允许的内存大小为 134217728 字节已用尽我尝试增加内存限制,但如果可能的话,我更愿意避免这种情况。
查看完整描述

3 回答

?
萧十郎

TA贡献1815条经验 获得超13个赞

应该会轻松一些。不需要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);

}


查看完整回答
反对 回复 2021-06-19
?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

更高的内存效率将是:

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


查看完整回答
反对 回复 2021-06-19
?
白衣非少年

TA贡献1155条经验 获得超0个赞

我也做了一些东西,但现在其他的更快了。: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:当然还有另一个函数可以总结相同的键,但不知何故我现在什么都没找到......我希望它有帮助:)


查看完整回答
反对 回复 2021-06-19
  • 3 回答
  • 0 关注
  • 156 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信