0

I'm pretty much self teaching myself to code and having a little play with creating a scraper app. I have an array I'm using in an json api but I need to flatten the structure so I can easily consume it elsewhere.

I'm really struggling to fathom out what I need to do here. I've read a load of other questions which are similar requests, but the array formats never match my format so I don't actually know how to tackle this.

This is the current array structure

{
    "result": [
        {
            "Boot buddy": {
                "id": "2",
                "groupno": "1",
                "urlsource": "https://www.amazon.co.uk/Boot-Buddy-fastest-simplest-footwear/dp/B014UPAHO4?pd_rd_wg=lVVK6&pd_rd_r=bf1ba871-fb59-4c66-a146-e94dde7c8e6d&pd_rd_w=gWC2F&ref_=pd_gw_ri&pf_rd_r=W68MX1TXFDDJ8Q8Z08CP&pf_rd_p=cecd4520-32f6-5499-ae19-cd4e83816acd",
                "name": "Boot buddy",
                "date": "2019-04-14 16:00:29.595,2019-04-14 21:50:31.362,2019-04-14 21:54:11.184",
                "price": "£14.99,£14.99,£14.99"
            },
            "Amazon echo": {
                "id": "1",
                "groupno": "1",
                "urlsource": "https://www.amazon.co.uk/dp/B07CH6JKW3/ref=gw_uk_desk_h1_aucc_cp_mp?pf_rd_p=e4e5a2e6-ddbd-473a-a5fb-e8cc09a11f88&pf_rd_r=1MN25BRXY8YDQ4TBK4X6",
                "name": "Amazon echo",
                "date": "2019-04-14 16:00:29.595,2019-04-14 21:50:31.362,2019-04-14 21:54:11.184",
                "price": "£14.99,£14.99,£14.99"
            }
        }
    ]
}

I want to achieve this

{
    "result": [
        {
            "id": "2",
            "groupno": "1",
            "urlsource": "https://www.amazon.co.uk/Boot-Buddy-fastest-simplest-footwear/dp/B014UPAHO4?pd_rd_wg=lVVK6&pd_rd_r=bf1ba871-fb59-4c66-a146-e94dde7c8e6d&pd_rd_w=gWC2F&ref_=pd_gw_ri&pf_rd_r=W68MX1TXFDDJ8Q8Z08CP&pf_rd_p=cecd4520-32f6-5499-ae19-cd4e83816acd",
            "name": "Boot buddy",
            "date": "2019-04-14 16:00:29.595,2019-04-14 21:50:31.362,2019-04-14 21:54:11.184",
            "price": "£14.99,£14.99,£14.99"
        },
        {
            "id": "1",
            "groupno": "1",
            "urlsource": "https://www.amazon.co.uk/dp/B07CH6JKW3/ref=gw_uk_desk_h1_aucc_cp_mp?pf_rd_p=e4e5a2e6-ddbd-473a-a5fb-e8cc09a11f88&pf_rd_r=1MN25BRXY8YDQ4TBK4X6",
            "name": "Amazon echo",
            "date": "2019-04-14 16:00:29.595,2019-04-14 21:50:31.362,2019-04-14 21:54:11.184",
            "price": "£14.99,£14.99,£14.99"
        }
    ]
}

This is the code I'm using to generate the array which then gets converted into json for use in the api. I'm iterating over a previous call to the database to merge duplicate records together but keep the unique date and price data. So maybe there's a way to change this code to get the output I'm after?

    $records=array();
    $records[result]=array();
    foreach ($products_arr[records] as $key => $value) {
        $hash = $value['name'];
        if(isset($result[$hash])){
            $result[$hash]['date'] .= ",{$value['date']}";
            $result[$hash]['price'] .= ",{$value['price']}";

        }else{
            $result[$hash] = $value;
        }
    }
    array_push($records[result], $result);

Any help appreciated!!

Chris
  • 109
  • 1
  • 8
  • 1
    `$yourArray['result'] = array_values($yourArray['result'])`? – Dharman Apr 21 '19 at 19:56
  • Creates an error @Dharman sorry – Chris Apr 21 '19 at 20:05
  • What error? What did you try? I cannot see your screen, remember? – Dharman Apr 21 '19 at 20:09
  • I'm using postman to consume the api and it kicks out this error which is actually relating to http response code for some reason, but it only occurs when I add the above line. This is the error...
    Parse error: syntax error, unexpected 'http_response_code' (T_STRING) in C:\xampp\htdocs\api\product\read-merged.php on line 79
    – Chris Apr 21 '19 at 20:10
  • You have forgot `;` after the previous line... – Dharman Apr 21 '19 at 20:11
  • kill me, thank you I'll give it a go – Chris Apr 21 '19 at 20:12
  • Ok no error, but the json output hasn't changed – Chris Apr 21 '19 at 20:13
  • Waoh! I'm not sure to be able to solve your problem, but I feel a bad approach: That all I can say with the elements you gave. The way you build a JSON yourself looks strange (most of the time to generate JSON, you build a PHP multidimensionnal array and then you turn it to json using `json_encode`). I think you should find an other approach. – Casimir et Hippolyte Apr 21 '19 at 21:07
  • Thanks, I start with a multi dimensional array. The complexity starts with me iterating over the entries to find duplicate products and the merging the price and date data together. Each scrape result is a new entry in the DB so they need mashing together. I actually found this which is a very similar problem, I just haven't been able to unpick it to apply to my problem https://stackoverflow.com/questions/28393612/flattening-a-json-multi-depty-array-in-php I am a complete noob so good chance approach is wrong, but I keep moving forward best I can! – Chris Apr 21 '19 at 21:15

2 Answers2

2

Like that:

$json=<<<'EOD'
{
    "result": [
        {
            "Boot buddy": {
                "id": "2",
                "groupno": "1",
                "urlsource": "https://www.amazon.co.uk/Boot-Buddy-fastest-simplest-footwear/dp/B014UPAHO4?pd_rd_wg=lVVK6&pd_rd_r=bf1ba871-fb59-4c66-a146-e94dde7c8e6d&pd_rd_w=gWC2F&ref_=pd_gw_ri&pf_rd_r=W68MX1TXFDDJ8Q8Z08CP&pf_rd_p=cecd4520-32f6-5499-ae19-cd4e83816acd",
                "name": "Boot buddy",
                "date": "2019-04-14 16:00:29.595,2019-04-14 21:50:31.362,2019-04-14 21:54:11.184",
                "price": "£14.99,£14.99,£14.99"
            },
            "Amazon echo": {
                "id": "1",
                "groupno": "1",
                "urlsource": "https://www.amazon.co.uk/dp/B07CH6JKW3/ref=gw_uk_desk_h1_aucc_cp_mp?pf_rd_p=e4e5a2e6-ddbd-473a-a5fb-e8cc09a11f88&pf_rd_r=1MN25BRXY8YDQ4TBK4X6",
                "name": "Amazon echo",
                "date": "2019-04-14 16:00:29.595,2019-04-14 21:50:31.362,2019-04-14 21:54:11.184",
                "price": "£14.99,£14.99,£14.99"
            }
        }
    ]
}
EOD;

$arr = json_decode($json, true);
$arr['result'] = array_values($arr['result'][0]);
$result = json_encode($arr);

In the orginal JSON string, the first level of the result key is an array with a single indexed item that gives once decoded to a multidimensionnal array the index 0. To turn all keys contained at this level to indexes, you only need to use the array_values PHP function.

Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
  • Sorry this is pretty much what @dharman suggest above, but it didn't change the output at all – Chris Apr 21 '19 at 20:23
  • @Chris: no it's not what dharman suggested above. Read carefully and see the demo: https://3v4l.org/CCgYF – Casimir et Hippolyte Apr 21 '19 at 20:28
  • @Chris: if you don't accept my answer I will go to war against all Chris of the world. – Casimir et Hippolyte Apr 21 '19 at 20:41
  • Yeah your right that really is working! The problem is I'm struggling to use it to solve my problem. The data I'm working with isn't converted to json format until the end of the document, its in an array. I was trying to swap out $arr for the actual name of the array. Hold on I'll post up the code I'm using to format the data. – Chris Apr 21 '19 at 20:43
  • @Chris: If you need to go more in depth in your explanations, please edit your question. – Casimir et Hippolyte Apr 21 '19 at 20:48
  • Yeah Ok, let me add a bit more detail. Thanks @Casimir help really is appreciated – Chris Apr 21 '19 at 20:49
  • Ok added more detail to the question which might help? – Chris Apr 21 '19 at 20:55
0

This should work

$json = '{
    "result": [
        {
            "Boot buddy": {
                "id": "2",
                "groupno": "1",
                "urlsource": "https://www.amazon.co.uk/Boot-Buddy-fastest-simplest-footwear/dp/B014UPAHO4?pd_rd_wg=lVVK6&pd_rd_r=bf1ba871-fb59-4c66-a146-e94dde7c8e6d&pd_rd_w=gWC2F&ref_=pd_gw_ri&pf_rd_r=W68MX1TXFDDJ8Q8Z08CP&pf_rd_p=cecd4520-32f6-5499-ae19-cd4e83816acd",
                "name": "Boot buddy",
                "date": "2019-04-14 16:00:29.595,2019-04-14 21:50:31.362,2019-04-14 21:54:11.184",
                "price": "£14.99,£14.99,£14.99"
            },
            "Amazon echo": {
                "id": "1",
                "groupno": "1",
                "urlsource": "https://www.amazon.co.uk/dp/B07CH6JKW3/ref=gw_uk_desk_h1_aucc_cp_mp?pf_rd_p=e4e5a2e6-ddbd-473a-a5fb-e8cc09a11f88&pf_rd_r=1MN25BRXY8YDQ4TBK4X6",
                "name": "Amazon echo",
                "date": "2019-04-14 16:00:29.595,2019-04-14 21:50:31.362,2019-04-14 21:54:11.184",
                "price": "£14.99,£14.99,£14.99"
            }
        }
    ]
}';

$arr = (array) json_decode($json)->result[0];
foreach($arr as $data){
  $newArr['result'][] = $data;
}
echo json_encode($newArr);