doudu3961 2018-10-17 15:30
浏览 54

重构从foreach到Laravel Collections的代码

I have a JSON file like that

{
    "20":{
        "0":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        },
        "1":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        },
        "2":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        },
        "3":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        },
        "4":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        },
        "5":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        },
        "6":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        }
    },
    "21":{
        "0":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        },
        "1":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        },
        "2":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        },
        "3":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        },
        "4":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        },
        "5":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        },
        "6":{
            "period":[
                {
                    "open": 350,
                    "close": 600
                },
                {
                    "open": 660,
                    "close": 900
                }
            ]
        }
    }

and I have an action that is is decoding this JSON to array, and pass with foreach-es step by step, get that data and then store it in Database.

One guy said me that it is possible to refactor all that action, so I will not have absolutely (or approximative) any foreach or if. Also he said that it is called representative/functional programming.

So, I found that concept and all that stuff, but also can't figure out how to do it. My imperial code:

$processingFile = file_get_contents(storage_path('hours.txt'));
$decodedFile = json_decode($processingFile, true);

$data = [];
$i = 0;
$batch = 10000;

foreach ($decodedFile as $business => $days) {
    foreach ($days as $dayOfWeek => $periods) {
        if (count($periods)) {
            foreach ($periods['period'] as $key => $value) { 
                $i++;  
                $tmp = [
                    'business_id' => $business,
                    'day_of_week' => $dayOfWeek,
                    'open_periods_mins' => $value['open'],
                    'close_periods_mins' => $value['close'],
                ];
                array_push($data, $tmp);
                if($i === $batch) {
                    BusinessHour::insert($data);
                    $data = [];
                    $i = 0;
                }
            }
        }
    }
}

if( count($data) ) {
    BusinessHour::insert($data); 
}

I don't know how to parse step by step and cut it all in functions using Laravel Collections or whatever... declarative paradigm.

Can someone explain / rewrite that code for teaching purpose? Thanks!

  • 写回答

2条回答 默认 最新

  • dorbmd1177 2018-10-17 21:19
    关注

    I am not sure if there are any universal ways that are applicable to your case, given the way you manipulate the information into the final array is not universal (for example, neither the string "period" nor the numerical keys in the period array is not used anywhere in the final output while the other keys are used, and the final two child elements are combined into one record, etc).

    Here is a bit techy way to prepare $data in your example, where the way in this answer to "PHP convert nested array to single array while concatenating keys?" is adopted. With this, it uses only one foreach (I think one-level loop is inevitable given the fiinal conversion is non-universal). Note it assumes the input JSON has no irregular structures.

    $string = http_build_query($decodedFile);
    $string = urldecode($string);
    $string = str_replace(
                  array('[',']'),
                  array('_','') , 
                  $string
              );
    parse_str($string, $flat_array);
    
    $data = [];
    $tmp = [];
    foreach ($flat_array as $ky => $val) {
        $ary = explode('_', $ky);
        $tmp[$ary[4] . '_periods_mins'] = $val;
        if ($ary[4] == 'close') {
            array_push($data, $tmp);
            $tmp = [];
            continue;
        }
        $tmp['business_id'] = $ary[0];
        $tmp['day_of_week'] = $ary[1];
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题