-3

I have an array like this:

[
    {
        "function_1": {
            "element": {
                "error": "0",
                "msg": "test"
            }
        }
    },
    {
        "function_1": {
            "element_2": {
                "error": "0",
                "msg": "test"
            }
        }
    },
    {
        "function_2": {
            "element": {
                "error": "0",
                "msg": "test"
            }
        }
    },
    {
        "function_2": {
            "element_2": {
                "error": "0",
                "msg": "test"
            }
        }
    }
]

I want output like this:

[
    {
        "function_1": {
            "element": {
                "error": "0",
                "msg": "test"
            },
            "element_2": {
                "error": "0",
                "msg": "test"
            }
        }
    },
    {
        "function_2": {
            "element": {
                "error": "0",
                "msg": "test"
            },
            "element_2": {
                "error": "0",
                "msg": "test"
            }
        }
    }
]

The answers that I found offered to search by name("function_1", "function_2"). But this does not suit me, the function will not always pass an array. I need exactly the "depth" or any other reasonable way. Thank you!

3
  • the added array data isn't valid ? Commented Nov 20, 2022 at 7:40
  • @OMiShah What do you mean? Commented Nov 20, 2022 at 8:16
  • the data format is incorrect. Is this JSON array output from some API? Commented Nov 20, 2022 at 8:33

3 Answers 3

1

To achieve your desired result, you could json-decode, recursively merge each individual subarray, then loop over that structure to push each item as a second-level array like this: (Demo)

$array = json_decode($json, true);
$merged = array_merge_recursive(...$array);

$result = [];
foreach ($merged as $key => $data) {
    $result[] = [$key => $data];
}
var_export($result);

But I can't imagine getting any benefit from adding unnecessary depth to your result array. I recommend simply json decoding, then calling array_merge_recursive() with the spread operator: (Demo)

var_export(
    array_merge_recursive(
        ...json_decode($json, true)
    )
);

Output:

array (
  'function_1' => 
  array (
    'element' => 
    array (
      'error' => '0',
      'msg' => 'test',
    ),
    'element_2' => 
    array (
      'error' => '0',
      'msg' => 'test',
    ),
  ),
  'function_2' => 
  array (
    'element' => 
    array (
      'error' => '0',
      'msg' => 'test',
    ),
    'element_2' => 
    array (
      'error' => '0',
      'msg' => 'test',
    ),
  ),
)
Sign up to request clarification or add additional context in comments.

1 Comment

To clear up any suspected hammer abuse: I did not find this duplicate until 5 days after answering. If I delete my answer now, then only suboptimal answers will be presented here. I'll leave this answer as viewable for researcher benefit. I support the removal of this page.
0

Your data structure looks weird for the purpose you are trying to achieve I'm bored af tho and created this code for you

function combineElementsPerfunction($functions) {

   $result = [];

    $uniqueFunctions = [];
    foreach ($functions as $function) {
        $functionName = array_keys($function)[0];
        $uniqueFunctions[] = $functionName;
    }
    $uniqueFunctions = array_unique($uniqueFunctions);
    foreach ($uniqueFunctions as $uniqueFunction) {
        $functionObjects = array_filter(
            $functions,
            function($function) use ($uniqueFunction) {
                $functionName = array_keys($function)[0];
                return $functionName === $uniqueFunction;
            }
        );
        
        $elements = [];
        foreach ($functionObjects as $functionObject) {
            $function = array_shift($functionObject);
            $elements = array_merge($elements, $function);
        }
        
        $result[] = [
            $uniqueFunction => $elements
        ];
    }
    return $result;
}

3 Comments

The amount of your code scares me. Can't this just be solved with a single foreach loop?
@Humster, and your expected output scares us!
This answer is missing its educational explanation, I hope your boredom is sufficient to improve this answer.
0
function changeArr($data){
    $box = $new = [];
    foreach ($data as $v){
        $key = array_key_first($v);
        $i = count($box);
        if(in_array($key, $box)){
            $keys = array_flip($box);
            $i = $keys[$key];
        }else{
            $box[] = $key;
        }
        $new[$i][$key] = isset($new[$i][$key]) ? array_merge($new[$i][$key], $v[$key]) : $v[$key];
    }
    return $new;
}

1 Comment

This answer is missing its educational explanation.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.