Reputation: 901
I can't figure out how to effectively convert the values of this array from a string to array. I really appreciate any suggestion.
array(6) {
["A"]=>
string(31) "['B' => 3, 'C' => 5, 'D' => 9],"
["B"]=>
string(41) "['A' => 3, 'C' => 3, 'D' => 4, 'E' => 7],"
["C"]=>
string(51) "['A' => 5, 'B' => 3, 'D' => 2, 'E' => 6, 'F' => 3],"
["D"]=>
string(51) "['A' => 9, 'B' => 4, 'C' => 2, 'E' => 2, 'F' => 2],"
["E"]=>
string(41) "['B' => 7, 'C' => 6, 'D' => 2, 'F' => 5],"
["F"]=>
string(31) "['C' => 3, 'D' => 2, 'E' => 5],"
}
Desired output:
$graph = [
'A' => ['B' => 3, 'C' => 5, 'D' => 9],
'B' => ['A' => 3, 'C' => 3, 'D' => 4, 'E' => 7],
'C' => ['A' => 5, 'B' => 3, 'D' => 2, 'E' => 6, 'F' => 3],
'D' => ['A' => 9, 'B' => 4, 'C' => 2, 'E' => 2, 'F' => 2],
'E' => ['B' => 7, 'C' => 6, 'D' => 2, 'F' => 5],
'F' => ['C' => 3, 'D' => 2, 'E' => 5],
];
Upvotes: 1
Views: 146
Reputation: 1571
Seems like you're trying to convert array string to an array.
You can repeat through loop or make function to get your desired output.
I'm using regular expression with preg_match_all
Code
$rawArray = array("A"=>"['B' => 3, 'C' => 5, 'D' => 9],",
"B"=>"['A' => 3, 'C' => 3, 'D' => 4, 'E' => 7],",
"C"=>"['A' => 5, 'B' => 3, 'D' => 2, 'E' => 6, 'F' => 3],",
"D"=>"['A' => 9, 'B' => 4, 'C' => 2, 'E' => 2, 'F' => 2],",
"E"=>"['B' => 7, 'C' => 6, 'D' => 2, 'F' => 5],",
"F"=>"['C' => 3, 'D' => 2, 'E' => 5],",
);
foreach($rawArray as $k => $v){
preg_match_all("/\'(.)\'/", $v, $key);
preg_match_all("/=> (\d)/", $v, $val);
$graph[$k] = array_combine($key[1], $val[1]);
}
print_r($graph);
Output
Array
(
[A] => Array
(
[B] => 3
[C] => 5
[D] => 9
)
[B] => Array
(
[A] => 3
[C] => 3
[D] => 4
[E] => 7
)
[C] => Array
(
[A] => 5
[B] => 3
[D] => 2
[E] => 6
[F] => 3
)
[D] => Array
(
[A] => 9
[B] => 4
[C] => 2
[E] => 2
[F] => 2
)
[E] => Array
(
[B] => 7
[C] => 6
[D] => 2
[F] => 5
)
[F] => Array
(
[C] => 3
[D] => 2
[E] => 5
)
)
Live demo
Explanation:
$rawArray is associate array, each of it's element contain string similar to php array.
We're looping through array and converting that string to array by using preg_match_all and building $graph multidimension array.
When loop execute first time $k
is equal to A
and $v
is equal to ['B' => 3, 'C' => 5, 'D' => 9],
First preg_match_all make array of keys from $v (['B' => 3, 'C' => 5, 'D' => 9],
), and assign it to $key[1]
. Now $key[1]
is array ['B', 'C', 'D']
.
Second preg_match_all make array of values from $v (['B' => 3, 'C' => 5, 'D' => 9],), and assign it to $val[1]
. Now $val[1]
is array [2, 5, 9]
.
We're combining$key[1]
as keys and $val[1]
as values by using array_combine to the $graph[$k]
where $k
is A
.
How preg_match_all works?
preg_match_all($pattern, $string, $out);
It's matches pattern from string and then assign result to the $out
as array.
Learn more about.
preg_match_all
regex pattern cheat sheet
Note: We're using non-capturing pattern so, it's return both exact match and desired match... So our desired record found in$key[1]
.
Upvotes: 3
Reputation: 631
A little ugly but I think this finally does the trick.
I downloaded your file and ran this locally so that the source is exactly as you stated. Then I proceeded to parse it and convert the string value to an actual array
Here's how it looks now:
// Parse graph.json file
$json = json_decode(file_get_contents('graph.json'), true);
foreach ($json as $key => $value) {
foreach ($value as $k => $val) {
$str = str_replace(['[', ']'], '', $val);
$str = str_replace(' => ', ',', $str);
$str = str_replace("'", "", $str);
$str = explode(',', $str);
for ($x = 0; $x < count($str); $x = $x + 2) {
$graph[$k][trim($str[$x])] = $str[$x+1];
}
}
}
// Result
echo "<pre>";
print_r($graph);
// Proof it is an array now (result 3)
// echo '<pre>';
// print_r($graph['A']['B']);
Final Result:
Array
(
[A] => Array
(
[B] => 3
[C] => 5
[D] => 9
)
[B] => Array
(
[A] => 3
[C] => 3
[D] => 4
[E] => 7
)
[C] => Array
(
[A] => 5
[B] => 3
[D] => 2
[E] => 6
[F] => 3
)
[D] => Array
(
[A] => 9
[B] => 4
[C] => 2
[E] => 2
[F] => 2
)
[E] => Array
(
[B] => 7
[C] => 6
[D] => 2
[F] => 5
)
[F] => Array
(
[C] => 3
[D] => 2
[E] => 5
)
)
If you run the below which is your expected output example and then compare the output to my output it is identical:
$graph = [
'A' => ['B' => 3, 'C' => 5, 'D' => 9],
'B' => ['A' => 3, 'C' => 3, 'D' => 4, 'E' => 7],
'C' => ['A' => 5, 'B' => 3, 'D' => 2, 'E' => 6, 'F' => 3],
'D' => ['A' => 9, 'B' => 4, 'C' => 2, 'E' => 2, 'F' => 2],
'E' => ['B' => 7, 'C' => 6, 'D' => 2, 'F' => 5],
'F' => ['C' => 3, 'D' => 2, 'E' => 5],
];
echo '<pre>';
print_r($graph);
Upvotes: 1
Reputation: 318
This is how you can do it,
<?php
$graph = array("A"=>"['B' => 3, 'C' => 5, 'D' => 9],",
"B"=>"['A' => 3, 'C' => 3, 'D' => 4, 'E' => 7],",
"C"=>"['A' => 5, 'B' => 3, 'D' => 2, 'E' => 6, 'F' => 3],",
"D"=>"['A' => 9, 'B' => 4, 'C' => 2, 'E' => 2, 'F' => 2],",
"E"=>"['B' => 7, 'C' => 6, 'D' => 2, 'F' => 5],",
"F"=>"['C' => 3, 'D' => 2, 'E' => 5],",
);
foreach ($graph as $key => $value) {
$val = str_replace("[","{",$value);
$val = str_replace("]","}",$val);
$val = str_replace("'",'"',$val);
$val = str_replace("=>",":",$val);
$val = rtrim($val, ',');
$graph[$key] = json_decode($val, true);
}
echo "<pre>";
print_r($graph);
echo "</pre>";
Output
Array
(
[A] => Array
(
[B] => 3
[C] => 5
[D] => 9
)
[B] => Array
(
[A] => 3
[C] => 3
[D] => 4
[E] => 7
)
[C] => Array
(
[A] => 5
[B] => 3
[D] => 2
[E] => 6
[F] => 3
)
[D] => Array
(
[A] => 9
[B] => 4
[C] => 2
[E] => 2
[F] => 2
)
[E] => Array
(
[B] => 7
[C] => 6
[D] => 2
[F] => 5
)
[F] => Array
(
[C] => 3
[D] => 2
[E] => 5
)
)
Upvotes: 1
Reputation: 2328
The proper answer is: don't create such a strange array ;) But since you did, this should do the trick:
//or $graph instead of $result
$result = array_map(function($value) {
//use eval to directly evaluate the string
//we just need to remove the trailing comma
//and add a semicolon
eval('$ret = '.rtrim($value,',').';');
return($ret);
}, $array); // replace $array with the var name of your array!
But remember: eval is evil. If you don't trust the input you need to write your own parser.
Temporary edit for clarification. This is what I get when I run your github example trough json_decode(...,true)
:
array(6) {
[0]=>
array(1) {
["A"]=>
string(30) "['B' => 3, 'C' => 5, 'D' => 9]"
}
[1]=>
array(1) {
["B"]=>
string(40) "['A' => 3, 'C' => 3, 'D' => 4, 'E' => 7]"
}
[2]=>
array(1) {
["C"]=>
string(50) "['A' => 5, 'B' => 3, 'D' => 2, 'E' => 6, 'F' => 3]"
}
[3]=>
array(1) {
["D"]=>
string(50) "['A' => 9, 'B' => 4, 'C' => 2, 'E' => 2, 'F' => 2]"
}
[4]=>
array(1) {
["E"]=>
string(40) "['B' => 7, 'C' => 6, 'D' => 2, 'F' => 5]"
}
[5]=>
array(1) {
["F"]=>
string(30) "['C' => 3, 'D' => 2, 'E' => 5]"
}
}
This differs from your question.
Upvotes: 0