Input string:
$times = '{endTime:"2017-03-29T17:15:00.000+11:00",startTime:"2017-03-29T17:00:00.000+11:00"},{endTime:"2017-03-31T17:15:00.000+11:00",startTime:"2017-03-31T17:00:00.000+11:00"},{endTime:"2017-04-01T12:15:00.000+11:00",startTime:"2017-04-01T12:00:00.000+11:00"}';
And I'm trying to convert it into an array that should look like this:
Array
(
[0] => Array
(
endTime => "2017-03-29T17:15:00.000+11:00"
startTime => "2017-03-29T17:00:00.000+11:00"
)
[1] => Array
(
endTime => "2017-03-31T17:15:00.000+11:00"
startTime => "2017-03-31T17:00:00.000+11:00"
)
[2] => Array
(
endTime => "2017-04-01T12:15:00.000+11:00"
startTime => "2017-04-01T12:00:00.000+11:00"
)
)
I've tried exploding, combining and all sorts but my code is so messy that I'm sure there must be a better and cleaner way?
This is MY cleanest starting point, but even this not clean, yes?
$times = '{endTime:"2017-03-29T17:15:00.000+11:00",startTime:"2017-03-29T17:00:00.000+11:00"},{endTime:"2017-03-31T17:15:00.000+11:00",startTime:"2017-03-31T17:00:00.000+11:00"},{endTime:"2017-04-01T12:15:00.000+11:00",startTime:"2017-04-01T12:00:00.000+11:00"}';
$timesarr = explode("},{", $times);
foreach ($timesarr as $i => $item) {
$timesarr[$i] = str_replace("{", "", $item);
$timesarr[$i] = str_replace("}", "", $timesarr[$i]);
$timesarr[$i] = explode(",", $timesarr[$i]);
}
echo '<pre>'; print_r($timesarr); echo '</pre>';
Improvements done:
Appended square braces at starting and end.
Replaced words with [a-zA-Z]+ with "[a-zA-Z]+" making it a valid json than json_decode
PHP code demo
<?php
$times = '{endTime:"2017-03-29T17:15:00.000+11:00",startTime:"2017-03-29T17:00:00.000+11:00"},{endTime:"2017-03-31T17:15:00.000+11:00",startTime:"2017-03-31T17:00:00.000+11:00"},{endTime:"2017-04-01T12:15:00.000+11:00",startTime:"2017-04-01T12:00:00.000+11:00"}';
$times=$times."]";
$times="[".$times;
$jsonString=preg_replace("/([a-zA-Z]+\s*)\:/", '"$1":', $times);
print_r(json_decode($jsonString,true));
This code will replace 'endTime' with '"endTime"' and same for startTime. I don't recommend you doing it this way, but it will work for you in this situation:
$times='{"endTime":"2017-03-29T17:15:00.000+11:00","startTime":"2017-03-29T17:00:00.000+11:00"},{"endTime":"2017-03-31T17:15:00.000+11:00","startTime":"2017-03-31T17:00:00.000+11:00"},{"endTime":"2017-04-01T12:15:00.000+11:00","startTime":"2017-04-01T12:00:00.000+11:00"}';
$times=str_replace("endTime",'"endTime"',$times);
$times=str_replace("startTime",'"startTime"',$times);
$times="[$times]";
echo "<h2><pre>";
print_r(json_decode($times,true));
This will output this:
Array
(
[0] => Array
(
[endTime] => 2017-03-29T17:15:00.000+11:00
[startTime] => 2017-03-29T17:00:00.000+11:00
)
[1] => Array
(
[endTime] => 2017-03-31T17:15:00.000+11:00
[startTime] => 2017-03-31T17:00:00.000+11:00
)
[2] => Array
(
[endTime] => 2017-04-01T12:15:00.000+11:00
[startTime] => 2017-04-01T12:00:00.000+11:00
)
)
Try this
First make the string a valid json string.
Add [ at start and ] at end. So your code will be
$times = '[{endTime:"2017-03-29T17:15:00.000+11:00",startTime:"2017-03-29T17:00:00.000+11:00"},{endTime:"2017-03-31T17:15:00.000+11:00",startTime:"2017-03-31T17:00:00.000+11:00"},{endTime:"2017-04-01T12:15:00.000+11:00",startTime:"2017-04-01T12:00:00.000+11:00"}]';
$result = json_decode($times, true);
This is not valid JSON, it looks like a bunch of JS variables concatenated together. You need a heavily customised parser:
<?php
$times = '{endTime:"2017-03-29T17:15:00.000+11:00",startTime:"2017-03-29T17:00:00.000+11:00"},{endTime:"2017-03-31T17:15:00.000+11:00",startTime:"2017-03-31T17:00:00.000+11:00"},{endTime:"2017-04-01T12:15:00.000+11:00",startTime:"2017-04-01T12:00:00.000+11:00"}';
$times = str_replace(["{","}"],["\0","\0"],$times); //replace {} with null bytes (they're hopefully unique and will be used as delimiters)
$csv = str_getcsv($times,",","\0"); //Treat string as a CSV enclosed in those null bytes
$csv = array_map(function ($v) {
$vars = explode(",",$v);
$arr = [];
foreach ($vars as $var) {
$parts = str_getcsv($var,":","\""); // endTime:"2017-03-29T17:15:00.000+11:00" is like a CSV split by : and enclosed in "
$arr[$parts[0]] = $parts[1];
}
return $arr;
},$csv);
print_r($csv);
Result:
Array
(
[0] => Array
(
[endTime] => 2017-03-29T17:15:00.000+11:00
[startTime] => 2017-03-29T17:00:00.000+11:00
)
[1] => Array
(
[endTime] => 2017-03-31T17:15:00.000+11:00
[startTime] => 2017-03-31T17:00:00.000+11:00
)
[2] => Array
(
[endTime] => 2017-04-01T12:15:00.000+11:00
[startTime] => 2017-04-01T12:00:00.000+11:00
)
)
Alternately walk away from this mess and demand your data be properly formatted as JSON.
Related
Lets suppose we have an array of arrays that needs to be converted to rows
From this:
Array
(
[subject] => Array
(
[0] => EDN:LOC:DERR
[1] => EDN:LOC:DOXX
[2] => EDN:LOC:NTTT
[3] => EDN:LOC:NAGA
)
[object] => Array
(
[0] => ABS:D01::ADFPAZ01
[1] => ABS:D01::DOXYWITX
[2] => ABS:D01::NAGBAAD2
[3] => ABS:D01::NAGGAAD2
)
[units] => Array
(
[0] => ABS:D06::UNAA
[1] => ABS:D06::UMMM
[2] => ABS:D06::UPOP
[3] => ABS:D06::UPOP
)
To this:
[0] => "'DERR' , 'ADFPAZ01' , 'UNAA'"
[1] => "'DOXX' , 'DOXYWITX' , 'UMMM'"
[2] => "'NTTT' , 'NAGBAAD2' , 'UPOP'"
[3] => "'NAGA' , 'NAGGAAD2' , 'UPOP'"
So I need the arrays to be cleaned by a pattern and compressed into lines.
I managed the compact view with the following function
$array_res = array();
for ($i=0; $i<=$totalEntries-1; $i++) {
array_push($array_res, implode("', '", array_column($array_of_arrays, $i)));
}
My regex pattern is $pattern = '([^.:]*$)'; And it collects a sequence of letters from the end of the string until it finds a colon. And I used preg_match($pattern, $string, $match) to receive the proper string into the $match variable.
However, I cannot combine the above two procedures either with array_filter or array_map inside the for loop.
EDIT: Note that there can be a subarray that contains values without a colon. In that case we have to get the value as is
[units] => Array
(
[0] => NULL
[1] => VALUE1
[2] => VALUE2
[3] => NULL
)
Rather than using a regex, this just uses array_walk() to process the extracted column and for each item it uses strrchr() with : as the last character to match (although it will include the :, so uses substr() to remove the first char)...
for ($i=0; $i<=$totalEntries-1; $i++) {
$newRow = array_column($array_of_arrays, $i);
array_walk($newRow, function (&$data) {
$data = substr(strrchr(":".$data, ":") , 1);
});
$array_res[] = "'".implode("', '", $newRow)."'";
}
The part ":".$data deals with the time when there is no : in the string, it will always ensure that it does find something to use.
Other way:
$arr = [
'subject' => [ 'EDN:LOC:DERR', 'EDN:LOC:DOXX', 'EDN:LOC:NTTT', 'EDN:LOC:NAGA' ],
'object' => [ 'ABS:D01::ADFPAZ01', 'ABS:D01::DOXYWITX', 'ABS:D01::NAGBAAD2', 'ABS:D01::NAGGAAD2' ],
'units' => [ 'ABS:D06::UNAA', 'ABS:D06::UMMM', 'ABS:D06::UPOP', 'ABS:D06::UPOP' ]
];
$res = [];
$fmt = "'%s', '%s', '%s'";
foreach ($arr['subject'] as $k => $v) {
$res[] = vsprintf($fmt, preg_replace('~^.*:~', '', array_column($arr, $k)));
}
print_r($res);
Notice: If you don't know in advance your array length, nothing forbids to build the format pattern dynamically (using str_repeat or implode).
Hello :) I am a beginner in PHP.
I tried several times but did not succeed
I would like to parse a String like :
[1,[01,11,12],[20,21,22]]
to
`
arr[0][0]=>1
arr[1][0]=>01
arr[1][1]=>11
arr[1][2]=>12
arr[2][0]=>20
arr[2][1]=>21
arr[2][2]=>22
`
You can split your string on a comma that is not enclosed by [ and ] using this regex (inspired by this answer) with preg_split:
,(?![^\[]*\])
and then trim surrounding [ and ] from the resultant parts and split those strings on commas into succeeding elements of the output array. For example:
$string = '[1,[01,11,12] ,4 ,5, [20,21,22]]';
$parts = preg_split('/,(?![^\[]*\])/', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
$output = array();
foreach ($parts as $part) {
$part = trim($part, '[] ');
$output[] = explode(',', $part);
}
print_r($output);
Output:
Array
(
[0] => Array
(
[0] => 1
)
[1] => Array
(
[0] => 01
[1] => 11
[2] => 12
)
[2] => Array
(
[0] => 4
)
[3] => Array
(
[0] => 5
)
[4] => Array
(
[0] => 20
[1] => 21
[2] => 22
)
)
Demo on 3v4l.org
If you're 100% certain of the source and safety of the string, you can also just use eval:
eval("\$output = $string;");
The result will be the same.
I have a string like this:
{ArrivalTime:300, ProductID:198, ArrivalDate:21/07/2017}, {ArrivalTime:582, ProductID:397, ArrivalDate:22/07/2017}
I used json_decode() but it's not working;
I need return array like this:
Array
(
[0] => Array
(
[ArrivalTime] => 300
[ProductID] => 198
[ArrivalDate] => 21/07/2017
)
[1] => Array
(
[ArrivalTime] => 582
[ProductID] => 397
[ArrivalDate] => 21/07/2017
)
)
Can you help me to do that? thanks.
You can try
str_split — Convert a string to an array
Syntax:
array str_split ( string $string [, int $split_length = 1 ] )
Example:
<?php
$str = "Hello Friend";
$arr1 = str_split($str);
print_r($arr1);
?>
Edit:
Output:
Array
(
[0] => H
[1] => e
[2] => l
[3] => l
[4] => o
[5] =>
[6] => F
[7] => r
[8] => i
[9] => e
[10] => n
[11] => d
)
Replace string name and array name your own.
Thank You.
Run follow code to analyse it:
function strAnalyse($str){
preg_match_all('/(?<={)[^{}]*(?=})/',$str,$match);
$result = array();
foreach($match[0] as $item){
$one =array();
$tmp = explode(',',$item);
foreach($tmp as $kv){
$a = explode(':',$kv);
$one[trim($a[0])] = trim($a[1]);
}
array_push($result,$one);
}
echo '<pre>';
print_r($result);
}
result:
Array
(
[0] => Array
(
[ArrivalTime] => 300
[ProductID] => 198
[ArrivalDate] => 21/07/2017
)
[1] => Array
(
[ArrivalTime] => 582
[ProductID] => 397
[ArrivalDate] => 22/07/2017
)
)
the json is invalid even if we add "[]" (array brackets)
value should be in the any one of the format :
string, number,object,array,true,false,null
in your case there is a date in the value field change it to string by enclosing ""(double quotes)
the key in your json is a string
for json key the string should be enclosed by ""(double quotes)
" chars "
offical documentation : http://www.json.org/
the correct json format for your json is
[{
"ArrivalTime": 300,
"ProductID": 198,
"ArrivalDate": "21 / 07 / 2017"
}, {
"ArrivalTime": 582,
"ProductID": 397,
"ArrivalDate": "22 / 07 / 2017"
}]
You need to wrap your "json" string with [] and quotes, of course (or check, why it not wrapped earlier):
[{"ArrivalTime": 300,"ProductID": 198,"ArrivalDate": "21 / 07 / 2017"}, {"ArrivalTime": 582,"ProductID": 397,"ArrivalDate": "22 / 07 / 2017"}]
Then it will be correct json format and json_decode() create correct array.
That is not a valid json format. But if you have such kinda string try this code:
$string = "{ArrivalTime:300, ProductID:198, ArrivalDate:21/07/2017}, {ArrivalTime:582, ProductID:397, ArrivalDate:22/07/2017}";
$key = $value = $resultArray= array();
$arrayJson = explode('}, ', $string);
foreach ($arrayJson as $arrayJsonRep) {
$repJson = str_replace('{', '', $arrayJsonRep);
$repJson = str_replace('}', '', $repJson);
$repJsonExp = explode(', ', $repJson);
foreach ($repJsonExp as $x) {
$repJsonExpfirst= explode(':', $x);
array_push($key, $repJsonExpfirst[0]);
array_push($value, $repJsonExpfirst[1]);
}
$finalArray = array_combine($key, $value);
array_push($resultArray, $finalArray);
}
print_r($resultArray);
I have a function that returns database results like so:
<?php print_r($homepagematches; ?>
Array
(
[0] => Array
(
[matchid] => 30
[matchtitle] => Testing This!
[matchaverage] => 1
[matchyoutubecode] => New Match
[casterid] => 1
[matchtype] =>
[matchdate] => 2013-05-24 02:19:49
[matchcasteryoutube] => http://youtube.com/huskystarcraft
[matchcaster] => HuskyStarcraft
)
[1] => Array
(
[matchid] => 27
[matchtitle] => Psy vs Camara
[matchaverage] => 1
[matchyoutubecode] => nefC9vkMfG8
[casterid] => 1
[matchtype] =>
[matchdate] => 2013-05-24 02:13:10
[matchcasteryoutube] => http://youtube.com/huskystarcraft
[matchcaster] => HuskyStarcraft
)
The function returns all matches within the last 3 days, What I am trying to figure out is how to reform the array so that I can display the matches under the day in which they were posted. I know a foreach loop is probably required for this, I just can't get my head around the concept I would need to implement.
$matchdate = '';
foreach($this->data['homepagematches'] as $match){
if($matchdate != date('m/d', strtotime($match['matchdate'])) || $matchdate == ''){
$homematch[date('m/d', strtotime($match['matchdate']))] = array(
"matchtitle" => $match['matchtitle']);
}
Basically I need the Array to look like:
Array
(
[05/24] => Array
(
[matchid] =>30
[matchtitle] => Testing This!
[matchyoutubecode] => New Match
[casterid] = 1
)
)
I think this should do it.
foreach($this->data['homepagematches'] as $match){
$tag = date('m/d', strtotime($match['matchdate']));
$data[$tag][] = array(
"matchid" => $match['matchid'],
"matchtitle" => $match['matchtitle'],
"matchyoutubecode" => $match['matchyoutubecode'],
"casterid" => $match['casterid']
);
}
print_r($data);
<?php
$MatchesByDate = array();
foreach($homepagematches as $match) {
list($matchdate,$time) = explode(" ",$match["matchdate"]); //split field into date and time
if( !isset($MatchesByDate[$matchdate]) )
$MatchesByDate[$matchdate] = array(); // If the array for that date doesnt exist yet make it
$MatchesByDate[$matchdate][] = $match; //Use the matchdate as a key and add to the array
}
$array = array("2011-September_38","2011-June_4","2010-November_9","2011-November_29","2010-December_19");
i want to sort this array strings as following, it should sort the year first, then it should sort the month,
DESIRED OUTPUT
Array ( [0] => 2010-Marh_19
[1] => 2010-November_9
[2] => 2011-June_4
[3] => 2011-September_38
[4] => 2011-November_29 )
I've tried something, could anyone bind my function to sort year then month http://codepad.org/skEiUkTC
Try this code:
<?php
$array = array("2011-September_38","2011-June_4","2010-November_9","2011-November_29","2010-December_19");
function monthCompare($a, $b) {
$da = strtotime(strstr($a, '_', true));
$db = strtotime(strstr($b, '_', true));
return $da > $db;
}
usort($array, "monthCompare");
print_r($array);
?>
OUTPUT
Array
(
[0] => 2010-November_9
[1] => 2010-December_19
[2] => 2011-June_4
[3] => 2011-September_38
[4] => 2011-November_29
)
So a simple solution to this, is to turn each of the values into a objects with DateTime::createFromFormat, sort them, and then outputting the values again.
Before i saw this question i had never played with DateTime objects, but they are awesome and easy to work with, and createFromFormat makes perfectly sense.
$array = array("2011-September_30","2011-June_4","2010-November_9","2011-November_29","2010-December_19");
foreach($array as $item)
{
$timestamps[] = DateTime::createFromFormat('Y-F_d',$item);
}
sort($timestamps);
foreach($timestamps as $timestamp)
{
$newarray[] = $timestamp->format('Y-F_d');
}
will give you
Array
(
[0] => 2010-November_09
[1] => 2010-December_19
[2] => 2011-June_04
[3] => 2011-September_30
[4] => 2011-November_29
)