将分号分隔的字符串转换为关联数组的数组,然后json编码


Convert a semicolon separated string to an array of associative arrays then json encode

我在将一组分号分隔的字符串转换为json时遇到了一些问题。

输入字符串:

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
我代码:

function my_wrap($val) {
    return '{"test":"' . $val. '"}';
}
$parts = explode(';', $string);
$parts = array_map('my_wrap', $parts);
$json = '[' . implode(',', $parts) . ']';
echo $json;

输出如下:

[{"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"}]

我想要的是:

[{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"}]

等等…

注意:我从API URL而不是从csv文件或其他东西获得上述输入字符串。

你可以试试这段代码,看看它是否像你想的那样工作吗?

//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);

您所描述的输出不是JSON。

当PHP已经有非常好的例程(例如JSON编码和CSV解析)时,不要发明自己的例程。

假设数据从文件开始....

$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);

当然,这将需要一些调整来处理错误条件和可能大于php工作内存的数据集。

<?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使用了很多正确的函数,但我发现函数语法造成了太多的膨胀,使代码更难阅读。而且,这个任务可以在一个循环中完成,因此它应该是。

代码(演示):

$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);

OP的注意事项,您不能手动制作json字符串。始终依靠json_encode()的准确性——它不会让你失望的。