1

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],
 ];
2
  • Please supply not only the input, but also the desired output. Saying "to an array" doesn't make sense in this context. Commented Jul 19, 2018 at 21:13
  • TinkerTenorSoftwareGuy, I have edited my post. I tried to use explode(), but I get undesirable results. Any tip, please? Commented Jul 19, 2018 at 21:20

4 Answers 4

3

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:

  1. $rawArray is associate array, each of it's element contain string similar to php array.

  2. We're looping through array and converting that string to array by using preg_match_all and building $graph multidimension array.

  3. When loop execute first time $k is equal to A and $v is equal to ['B' => 3, 'C' => 5, 'D' => 9],

  4. 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'].

  5. 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].

  6. 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].

Sign up to request clarification or add additional context in comments.

8 Comments

Smartpal, I really appreciate your help. But what I mentioned above the desired output I neeed. I am trying to parse JSON with PHP. The original code is here, please check: github.com/mestre-c/php2018/blob/master/dao-tech-task/…
I was thinking along these lines. You can get the keys and values with just one preg_match_all, btw.
@Don'tPanic Yes, we can by joining regex pattern together, but it's more easy to understand step-by-step!
Smartpal, one main point, just right after the foreach, I've converted the value ($v), which is an array to string by doing this: $v = implode(",", $v);. By the way, Can you please explain the preg_math_all() methods? What exactly are they replacing?
@Capfer explained
|
1

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
        )

)

3 Comments

thezeeshantariq, Thanks a lot. But if I do this way? my code is gonna break. Please plase, check the original gson file that I am trying to parse: github.com/mestre-c/php2018/blob/master/dao-tech-task/…
I expect exactly the desired output above mentioned.
let me check, what I can do
1

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

1 Comment

dmotors, Thank you very much. Everything is working great. I've just seen your answer, so I had already voted above. I really appreciate your help.
0

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.

7 Comments

jh1711, thanks. I am getting some warnings: Warning: rtrim() expects parameter 1 to be string, array given; syntax error, unexpected ';' : eval()'d code
Strange. I used this script to test: 3v4l.org/Z4m56. And the input seems to be identical to your array.
@Capfer, could you please run array_map('var_dump',$array);, and confirm/deny that it looks similar to the output in your question (just without the array keys). The rtrim warning baffles me.
Just a point! The keys are strings, and that's fine for me. But I need the convert the values to an array. I am trying to parse JSON with PHP. This is the original code on my GitHub: github.com/mestre-c/php2018/blob/master/dao-tech-task/…
@Capfer, I added the (poorly formatted) output I get from your github.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.