4

I am querying an API and it sends a JSON response which I am then decoding into an array. This part works fine, but the API sends the information in a rather unfriendly format.

I will paste the part I am having issues with. Essentially I am trying to change each like keys into their own array.

Array
(
    [name] => Name
    [address] => 123 Street Rd
    [products[0][product_id]] => 1
    [products[0][price]] => 12.00
    [products[0][name]] => Product Name
    [products[0][product_qty]] => 1
    [products[1][product_id]] => 2
    [products[1][price]] => 3.00
    [products[1][name]] => Product Name
    [products[1][product_qty]] => 1
    [systemNotes[0]] => Note 1
    [systemNotes[1]] => Note 2
)

Now what I would like to do is to make it like this:

Array
(
    [name] => Name
    [address] => 123 Street Rd
    [product] => Array
    (
        [0] => Array
        (
            [product_id] => 1
            [price] => 12.00
            [name] => Product Name
            [product_qty] => 1
        )
        [1] => Array
        (
            [product_id] => 2
            [price] => 3.00
            [name] => Product Name
            [product_qty] => 1
        )
    [systemNotes] => Array
    (
        [0] => Note 1
        [1] => Note 2
    )
)

Is there any practical way of doing this?

Thanks!

1
  • Is the first example actually print_r output? I've never seen structure like that even with decoded JSON. If it is, please add a sample of the JSON which parses to that structure so I can wrap my brain around it properly. Commented Jul 19, 2013 at 0:13

2 Answers 2

6

References are your friend here:

$result = array();

foreach ($inputArray as $key => $val) {
    $keyParts = preg_split('/[\[\]]+/', $key, -1, PREG_SPLIT_NO_EMPTY);

    $ref = &$result;

    while ($keyParts) {
        $part = array_shift($keyParts);

        if (!isset($ref[$part])) {
            $ref[$part] = array();
        }

        $ref = &$ref[$part];
    }

    $ref = $val;
}

Demo


However, there is another, much simpler way, although it is a little less efficient in terms of functional complexity:

parse_str(http_build_query($inputArray), $result);

Demo

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

4 Comments

+1 - Nice! But this was such a rare opportunity to troll all the regex "experts" and write the regex as /[][]+/! (Trust me, it works.)
@acheong87 If you like the first version try the second ;-)
I was about to say, your edit blew my mind. Expect upvotes elsewhere for compensation.
Wow I had no idea that http_build_query would do that! Going to give both of these a try! Thank you very much you saved my butt!
0

With $array your source array :

$new_array = array("name" => $array["name"], "address" => $array["address"]);
foreach($array["products"] AS $product)
{
    $new_array["product"][] = array(
        "product_id" => $product["produit_id"],
        "price" => $product["price"],
        "name" => $product["name"],
        "product_qty" => $product["product_qty"]);
}

foreach($array["systemNotes"] AS $note)
{
   $new_array["systemNotes"][] = $note;
}

It is just browsing and creating a new structure. ^^

Edit : Something generic could be done recursively. Calling the same function as long as the browsed element is_array, and building a new array according to the keys and values. Looks like a file system ^^

5 Comments

I think he's looking for a generic solution.
Unfortunately, the base array is nothing like "generic"... Or else we don't have enough information about the problem.
I disagree, I guess. I'd say a generic solution would be something like, "If the key has balanced square brackets, then parse." The parsing would "explode" the key into a new subarray such that the key would successfully access its value were the key itself interpolated as a variable.
Edited original answer. If the original content is an array, recursivity sounds good to me. However if the first sample is a string, I'm afraid that was terribly wrong.
Well, I'm not the one who downvoted you, so please don't lash out on me, as I've known some SO'ers to do. I'm not sure what you mean by the "first sample" being a string---if you'd explain, I'd listen---but it's alright if you don't feel inclined to.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.