【问题标题】:PHP Create a Nested Array with indexes from a CSV filePHP 使用 CSV 文件中的索引创建嵌套数组
【发布时间】:2020-05-14 06:16:13
【问题描述】:

我遇到了一个特殊的问题。我有一个 CSV 文件,其中包含我需要上传的逗号分隔值,然后根据以下 3 个条件获取值的嵌套数组;

  1. 数组将首先遍历所有值并获取前 4 个唯一值 人物。 (代码)
  2. 将每列的值与与数量相匹配 每行中的列并给出匹配 4 位的行数 代码。 (单列的 Single_Devices 和各自列数的 Dual、Triple 和 Quad)
  3. 将每列值与代码匹配并列出所有 设备下的列。 (数字)

CSV 文件

123429000000000
123429000000001
123429000000010,123429000000011
123429000000040,123429000000041

我想要的是;

Array
(
    [Code] => 1234
        (
            [single_devices] => 2
                (
                    [0] => Array
                        (
                            [0] => 123429000000000
                        )
                    [1] => Array
                        (
                            [0] => 123429000000001
                        )
                )
            [dual_devices] => 2
                (
                    [0] => Array
                        (
                            [0] => 123429000000010
                            [1] => 123429000000011
                        )
                    [1] => Array
                        (
                            [0] => 123429000000040
                            [1] => 123429000000041
                        )
                )
        )

)

有可能吗? 我可以管理 JSON 转换的数据或对象,或者只是关联嵌套数组。

编辑:这是我编写的代码,它只显示值而不是我想要的索引。

// Get all numbers in array
for ($j = 0; $j < count($csv_file[$i]); $j++){
    $numbers[] = $csv_file[$i][$j];
}

// Get codes from numbers
for ($i = 0; $i < count($csv_file); $i++){
    for ($j = 0; $j < count($csv_file[$i]); $j++){
        $codes[] = substr($csv_file[$i][$j], 0, 4);
    }
}

// Get unique codes from codes array
$codes = array_unique($codes);

// Get numbers and sort them codes and device count wise.
for ($i = 0; $i < count($csv_file); $i++){
    for ($j = 0; $j < count($csv_file[$i]); $j++){
        $q = count($csv_file[$i]); // set device count based on column count
        if (count($csv_file[$i]) == $q){ // if device count is equal to column count
            foreach ($codes as $code){ // loop through unique codes
                if ($code == substr($csv_file[$i][$j], 0, 4)){ // if number's first 4 char matches code
                    // create array with code and then device count and add numbers
                    $devices[$code][$q.'_device_numbers'][$i][$j] = preg_replace('/\s+/', '', $csv_file[$i][$j]);
                }
            }
        }
    }
}

这是我从上面的代码中得到的。

Array
(
    [1234] => Array
        (
            [1_sim_imeis] => Array
                (
                    [0] => Array
                        (
                            [0] => 123429000000000
                        )

                    [1] => Array
                        (
                            [0] => 123429000000001
                        )

                )

            [2_sim_imeis] => Array
                (
                    [2] => Array
                        (
                            [0] => 123429000000010
                            [1] => 123429000000011
                        )

                    [3] => Array
                        (
                            [0] => 123429000000040
                            [1] => 123429000000041
                        )

                )

        )

)

【问题讨论】:

  • 有可能吗? - 是的,所以自己尝试一下并将代码添加到您的问题中。
  • 请不要只求我们为您解决问题。向我们展示您是如何尝试自己解决问题的,然后向我们确切展示结果是什么,并告诉我们您为什么觉得它不起作用。向我们明确解释什么不起作用并提供a Minimal, Complete, and Verifiable example。阅读How to Ask 一个好问题。请务必take the tour 并阅读this
  • 你需要逐行阅读,放入一个带有explode的数组,计算索引号,然后用你的逻辑放入一个数组。祝你好运。当您有真正的代码时,我们可以为您提供帮助。
  • 是否有可能在同一行中有多个项目,但这些项目的起始 4 个数字不同?
  • 是的@NigelRen 我已经编辑了我的问题。

标签: php arrays loops multidimensional-array associative-array


【解决方案1】:

这是基于以 csv 格式读取文件(使用 fgetcsv())并提取每行第一个值的前 4 位数字。然后它使用另一个数组来为 'single_devices' 等键提供键 - 使用行上元素数的计数(-1,因为数组是基于 0 的)...

$fileName = "a.dat";
$output = [];
$baseData = [ 'single_devices', 'dual_devices', 'triple_devices', 'quad_devices' ];
$fh = fopen ( $fileName, "r" );
while ( ($data = fgetcsv($fh)) !== false )  {
    $code = substr($data[0], 0, 4);
    $output[$code][$baseData[count($data)-1]][] = $data;
}

fclose($fh);

print_r($output);

测试数据给出的...

Array
(
    [1234] => Array
        (
            [single_devices] => Array
                (
                    [0] => Array
                        (
                            [0] => 123429000000000
                        )

                    [1] => Array
                        (
                            [0] => 123429000000001
                        )

                )

            [dual_devices] => Array
                (
                    [0] => Array
                        (
                            [0] => 123429000000010
                            [1] => 123429000000011
                        )

                    [1] => Array
                        (
                            [0] => 123429000000040
                            [1] => 123429000000041
                )

        )

)

while ( ($data = fgetcsv($fh)) !== false )  {
    $code = substr($data[0], 0, 4);
    if ( !isset($output[$code]))    {
        $output[$code] = ["code" => $code];
    }
    $deviceLabel = $baseData[count($data)-1];
    $output[$code][$deviceLabel]['count'] =
        ($output[$code][$deviceLabel]['count'] ?? 0) + 1;
    $output[$code][$deviceLabel][] = $data;
}

你可以得到...的输出

Array
(
    [1234] => Array
        (
            [code] => 1234
            [single_devices] => Array
                (
                    [count] => 2
                    [0] => Array
                        (
                            [0] => 123429000000000
                        )

                    [1] => Array
                        (
                            [0] => 123429000000001
                        )

                )

【讨论】:

  • 没错。这就是我目前使用我已经拥有的代码所得到的。但这不是我想要的数组。
  • 如果你的意思是你想要[Code] =&gt; 1234 ([single_devices] =&gt; 2 (,那不是一个有效的数组格式。您可以为它们添加额外的字段。
  • @Xia 这就是我上一条评论的意思。你说你想要的结果是不可能的。这就是为什么我要求您展示我们可以产生的结果,或者您如何提出您的要求。
  • @NigelRen 是的,这有点像我的目标。好的,所以它可能不是有效的数组格式,但正如我所提到的,是否有可能以任何其他方式获得这样的输出?
  • @PatrickQ 是的,我编辑了我的答案并添加了我得到的输出。
猜你喜欢
  • 2018-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-05
相关资源
最近更新 更多