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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.