1

I am facing some problems while converting a set of semicolon delimited strings to json.

The input string:

si;dialed_no;connect_time;duration;region;call_cost
0;918592877727;2015-08-25 18:51:01;21;India(91);0.029
1;918907777727;2015-08-25 19:04:08;220;India(91);0.232
2;918907777727;2015-08-25 19:09:50;40;India(91);0.058
3;918907777727;2015-08-25 19:10:46;69;India(91);0.087
4;919048232151;2015-08-26 13:30:24;19;India(91);0.029
5;919895842822;2015-08-26 14:23:35;423;India(91);0.435

My code:

function my_wrap($val) {
    return '{"test":"' . $val. '"}';
}

$parts = explode(';', $string);
$parts = array_map('my_wrap', $parts);
$json = '[' . implode(',', $parts) . ']';

echo $json;

And the output is like:

[{"test":"dialed_no"},{"test":"connect_time"},{"test":"duration"},{"test":"region"},{"test":"call_cost 0"},{"test":"918592877727"},{"test":"2015-08-25 18:51:01"},{"test":"21"},{"test":"India(91)"},{"test":"0.029 1"},{"test":"918907777727"},{"test":"2015-08-25 19:04:08"},{"test":"220"},{"test":"India(91)"},{"test":"0.232 2"},{"test":"918907777727"},{"test":"2015-08-25 19:09:50"},{"test":"40"},{"test":"India(91)"},{"test":"0.058 3"},{"test":"918907777727"},{"test":"2015-08-25 19:10:46"},{"test":"69"},{"test":"India(91)"},{"test":"0.087 4"},{"test":"919048232151"},{"test":"2015-08-26 13:30:24"},{"test":"19"},{"test":"India(91)"},{"test":"0.029 5"},{"test":"919895842822"},{"test":"2015-08-26 14:23:35"},{"test":"423"},{"test":"India(91)"},{"test":"0.435 6"},{"test":"8801711788025"},{"test":"2015-08-30 19:29:48"},{"test":"1"},{"test":"Bangladesh(880)"},{"test":"0.029 7"},{"test":"8801711788025"},{"test":"2015-08-30 19:29:57"},{"test":"2"},{"test":"Bangladesh(880)"},{"test":"0.029 8"},{"test":"8801711788025"},{"test":"2015-08-30 19:30:07"},{"test":"2"},{"test":"Bangladesh(880)"},{"test":"0.029 9"},{"test":"8801711788025"},{"test":"2015-08-30 19:30:17"},{"test":"1"},{"test":"Bangladesh(880)"},{"test":"0.029 10"},{"test":"8801711788025"},{"test":"2015-08-30 21:24:31"},{"test":"88"},{"test":"Bangladesh(880)"},{"test":"0.087 11"},{"test":"8801833316038"},{"test":"2015-08-31 12:06:15"},{"test":"5"},{"test":"Bangladesh(880)"},{"test":"0.029 12"}]

What I want is like:

[{si:"0",dialed_no:"91xxx",connect_time:"2015-08-25 18:51:01"}, {si:"1",dialed_no:"9184sd",connect_time:"2015-08-25 18:51:01"}]

and so on...

Note: I am getting the above input string from a API URL and not from a csv file or something.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Arun Code
  • 1,548
  • 1
  • 13
  • 18

4 Answers4

0

What you described as the output you want is not JSON.

Don't invent your own routines when PHP already has perfectly good ones (e.g. for JSON encoding and CSV parsing).

Assuming that the data is starting in a file....

$data=array();
$y=0;
$header=fgtetcsv($file_handle, 0, ';');
while (!feof($file_handle)) {
    $row=fgtetcsv($file_handle, 0, ';');
    foreach ($row as $x=>$value) {
       $data[$y][$header[$x]]=$value;
    }
    $y++;
}
print json_encode($data);

Of course this will need some tweaks to handle error conditions and possibly for datasets larger than the working memory of php.

symcbean
  • 47,736
  • 6
  • 59
  • 94
  • I am getting the above input string from an API URL, however the response from the URL is not JSON and it is like plain text what I mentioned above. So I want to convert it into JSON first and then reuse it in other parts of my code. – Arun Code Oct 05 '15 at 13:55
0

Can you try this code and see if it works as you want?

//we split the single lines
$lines = explode("\n", $string);

$linesArray = array();

//we split each line in a set of elements
foreach($lines as $line){
   $linesArray[] = explode(";",$line);
}
//we use the first line of data as an array of headers
$headers = $linesArray[0];
//and remove it
unset($linesArray[0]);

$jsonArray = [];

foreach($linesArray as $l=>$ln){
    foreach($ln as $k=>$part){
        //we re-build an array with the right headers
        $jsonArray[$l][$headers[$k]] = $part;
    }
}

print json_encode($jsonArray);
nowhere
  • 1,558
  • 1
  • 12
  • 31
0
<?php
$records = array_map(
    function($e) {  // 2: to each line/record apply this functions
        return str_getcsv($e, ';');  // 3: split the line/record into fields
    },
    explode( "\n", data() ) // 1: split data into "lines"/records
);
// 4: now $records is an array of records, each being an array of fields
$fields = array_shift($records); // 5: first record contains the field names, remove from array and assign to $fields
$records = array_map(
    function($e) use ($fields) { // 7: this function has access to $fields, i.e. the names of the fields
        return array_combine($fields, $e);  // 8: see http://docs.php.net/array_combine
    },
    $records // 6: apply the function above to each element, i.e. record, in $records
);

echo json_encode($records);




function data() {
    return <<< eot
si;dialed_no;connect_time;duration;region;call_cost
0;918592877727;2015-08-25 18:51:01;21;India(91);0.029
1;918907777727;2015-08-25 19:04:08;220;India(91);0.232
2;918907777727;2015-08-25 19:09:50;40;India(91);0.058
3;918907777727;2015-08-25 19:10:46;69;India(91);0.087
4;919048232151;2015-08-26 13:30:24;19;India(91);0.029
5;919895842822;2015-08-26 14:23:35;423;India(91);0.435
eot;
}
VolkerK
  • 95,432
  • 20
  • 163
  • 226
  • wow do you have any reference where is explained how "use" works like you did in that anonymous function? – nowhere Oct 05 '15 at 14:35
  • It's more a list ;-) And it would include: http://docs.php.net/functions.anonymous , https://wiki.php.net/rfc/closures and http://stackoverflow.com/questions/1065188/in-php-5-3-0-what-is-the-function-use-identifier – VolkerK Oct 05 '15 at 14:55
  • I can't believe I never used something this useful! Thanks for the links! – nowhere Oct 05 '15 at 15:01
0

While I appreciate that VolkerK is using a lot of the right functions, I find that functional syntax creates too much bloat and makes the code harder to read. Furthermore, this task can be accomplished in a single loop and therefore it should be.

Code: (Demo)

$input = <<<SSV
si;dialed_no;connect_time;duration;region;call_cost
0;918592877727;2015-08-25 18:51:01;21;India(91);0.029
1;918907777727;2015-08-25 19:04:08;220;India(91);0.232
2;918907777727;2015-08-25 19:09:50;40;India(91);0.058
3;918907777727;2015-08-25 19:10:46;69;India(91);0.087
4;919048232151;2015-08-26 13:30:24;19;India(91);0.029
5;919895842822;2015-08-26 14:23:35;423;India(91);0.435
SSV;

$lines = explode(PHP_EOL, $input);
$header = str_getcsv(array_shift($lines), ';');
foreach ($lines as $line) {
    $result[] = array_combine($header, str_getcsv($line, ';'));    
}
echo json_encode($result, JSON_PRETTY_PRINT);

A note to the OP, you must not manually craft a json string. Always rely on the accuracy of json_encode() -- it won't fail you.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136