PHP数组合并,忽略某些重复的键,并将其包含在内部创建的数组中 [英] PHP array merging, ignore certain duplicated keys and let them be included in the inner created arrays

查看:65
本文介绍了PHP数组合并,忽略某些重复的键,并将其包含在内部创建的数组中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm merging together arrays with the same set inner array name, changing the key value to the order number then creating further inner arrays for items that are not duplicated with this code...

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相同,所以在我需要的时候它会被过滤掉.

So because qty = 1 is the same its getting filtered out, when what I need is..

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个项目,则即使内部数组相同,qty现在也需要所有6个项目在内部数组中.

How can I exclude certain ones from the "remove duplicates" part so they are repeated in an inner-array as in my last example? This is needed as they are directly linked to other items with an inner array, so if for example the item1 inner array now has 6 items the qty now needs to also have all 6 items in the inner array, even if they are the same.

推荐答案

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

Your current code is good for two cases:

  1. 按原样读取所有数据,无需修改
  2. 读取所有数据并进行通用修改

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

Since what you need is a conditional modification, it seems like you would be better off creating the structure of the array manually. Doing so would add another benefit: code clarity. You should always strive for descriptive code, so building your array with descriptive associative keys would make the intent of the code clearer.

基于示例数据的拟议解决方案(您应根据自己的特定需求进行粗略设计):

Proposed solution based off the example data (rough sketch that you should tailor to your specific needs):

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

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

Now all the items of your order are neatly stored as subarrays, each containing only data specific to that item, which makes it really easy to iterate:

foreach($orders[$orderId]['items'] as $item)

这篇关于PHP数组合并,忽略某些重复的键,并将其包含在内部创建的数组中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆