PHP数组合并,忽略某些重复的键,并将其包含在内部创建的数组中

问题描述 投票:0回答:1

我将具有相同设置的内部数组名称的数组合并在一起,将键值更改为订单号,然后为未使用此代码重复的项目创建其他内部数组...

function readCSV($csvFile)
    {
        $line_of_text = [];
        $file_handle = fopen($csvFile, 'r');
        //skip csv headers
        //fgetcsv($file_handle);
        //fgetcsv($file_handle);
        fgetcsv($file_handle);  
        while (!feof($file_handle)) {
            $tmp = fgetcsv($file_handle, 1024);

            if (isset($line_of_text[$tmp[0]])) {
                foreach ($tmp as $k => $v) {

                    if (array_key_exists($k, $line_of_text[$tmp[0]])) {
                        if (!is_array($line_of_text[$tmp[0]][$k])) {
                            $kVal = $line_of_text[$tmp[0]][$k];

                            $line_of_text[$tmp[0]][$k] = [];
                            $line_of_text[$tmp[0]][$k][] = $kVal;
                        }

                        $line_of_text[$tmp[0]][$k][] = $v;
                        $line_of_text[$tmp[0]][$k] = array_unique($line_of_text[$tmp[0]][$k]);
                        $line_of_text[$tmp[0]][$k] = array_filter($line_of_text[$tmp[0]][$k]);

                        if (count($line_of_text[$tmp[0]][$k]) == 1) {
                            $line_of_text[$tmp[0]][$k] = array_values($line_of_text[$tmp[0]][$k]);
                            $line_of_text[$tmp[0]][$k] = $line_of_text[$tmp[0]][$k][0];
                        }

                        if (empty($line_of_text[$tmp[0]][$k])) {
                            $line_of_text[$tmp[0]][$k] = null;
                        }

                    } else {
                        $line_of_text[$tmp[0]][$k] = null;
                    }
                }
                $line_of_text[$tmp[0]][0] = $tmp[0];

            } else {
                $line_of_text[$tmp[0]] = $tmp;
            }

        }

        fclose($file_handle);
        return array_filter(array_values($line_of_text));
    }

    // Set path to CSV file
    $csvFile = 'my.csv';
    $csv = readCSV($csvFile);

//$csv is your array
foreach($csv as $key => $value){
 if(!array_key_exists(@$value[0],$arr)){
  $arr[@$value[0]] = [];
  }
  $arr[@$value[0]] = array_merge($arr[@$value[0]],$value);  
}
echo "<pre>";
print_r($arr);
echo '</pre>'; 

此转弯..

Array
(
    [0] => Array
        (
            [0] => 15304
            [1] => item1
            [2] => qty = 1
        )

    [1] => Array
        (
            [0] => 15304
            [1] => item2
            [2] => qty = 1
        )

    [2] => Array
        (
            [0] => 15305
            [1] => itemX
            [2] => qty = 2
        )
}

进入

Array
(
    [15304] => Array
        (
            [0] => 15304
            [1] => Array
                (
                [0]item1
                [1]item2
                )
            [2] => qty = 1
        )

    [15305] => Array
        (
            [0] => 15305
            [1] => itemX
            [2] => qty = 2
        )
}

因此,由于qty = 1相同,因此当我需要时,它会被滤除。

Array
(
    [15304] => Array
        (
            [0] => 15304
            [1] => Array
                (
                [0]item1
                [1]item2
                )
            [2] => Array
                (
                [0]qty = 1
                [1]qty = 1
                )
        )

    [15305] => Array
        (
            [0] => 15305
            [1] => itemX
            [2] => qty = 2
        )
}

我如何从“删除重复项”部分中排除某些内容,以便像我上一个示例一样在内部数组中重复这些内容?这是必需的,因为它们直接通过内部数组链接到其他项目,因此,例如,如果item1内部数组现在有6个项目,则即使内部数组相同,数量也需要在内部数组中拥有所有6个项目。

php arrays associative-array array-merge
1个回答
0
投票

您当前的代码在两种情况下都适用:

  1. 读取所有数据原样,未经修改
  2. 读取所有数据并进行通用修改

因为您需要的是条件修改,所以似乎最好手动创建数组的结构。这样做会增加另一个好处:代码清晰。您应该始终争取使用描述性代码,因此使用描述性关联键构建数组将使代码的意图更加清晰。

基于示例数据的建议解决方案(您应根据自己的特定需求定制草图):

function readCSV($csvFile)
{
    $output = [];
    $fileHandle = fopen($csvFile, 'r');
    $header = fgetcsv($fileHandle);
    while (!feof($fileHandle)) {
        $fileRow = fgetcsv($fileHandle, 1024);
        $orderId = $fileRow[0];
        // skip this row if it's empty (the first field contains no id)
        if (empty($orderId)) {
            continue;
        }
        /*
          $fileRow[3] is "Buyer name", the first field that's present in one type of row
          (the one containing common properties of the order). By checking if it's empty,
          we identify the contents of the row - not empty means order row with common
          properties, empty means item row with specific item properties.
         */
        if (!empty($fileRow[3])) {
            // no need to repeat the id inside the array - it's already stored in the key
            $output[$orderId] = [
                'order_number' => $fileRow[1],
                'buyer_username' => $fileRow[2],
                'buyer_name' => $fileRow[3],
                // here you can continue explicitly adding any property you need
            ];
        } else {
            // add a new item entry
            $output[$orderId]['items'][] = [
                'item_number' => $fileRow[20],
                'item_title' => $fileRow[21],
                'quantity' => $fileRow[24],
                'price' => $fileRow[25],
                // here you can continue explicitly adding any property you need
            ];
        }
    }
    fclose($fileHandle);

    return $output;
}

现在,您订单中的所有项目都被整齐地存储为子数组,每个子数组仅包含特定于该项目的数据,这使得迭代非常容易:

foreach($orders[$orderId]['items'] as $item)
© www.soinside.com 2019 - 2024. All rights reserved.