1

I have data like I have pasted bellow. I want to combine on the basis of name i.e abc name template is in different language i want it in the information name, category and All its languages on the same index.

[{
    "name": "abc",
    "category": "new_cat",
    "selectedLanguage": [{
        "de": "Deutsch",
        "de_status": "APPROVED"
    }]
}, {
    "name": "abc",
    "category": "new_cat",
    "selectedLanguage": [{
        "en": "English",
        "en_status": "APPROVED"
    }]
}, .... 

As mentioned above I want the result as json pasted below.

[{
    "name": "abc",
    "category": "new_cat",
    "selectedLanguage": [{
        "de": "Deutsch",
        "de_status": "APPROVED"
    }, {
        "en": "English",
        "en_status": "APPROVED"
    }]
},...{
    "name": "unique_temp",
    "category": "TICKET_UPDATE",
    "selectedLanguage": [{
        "en": "English",
        "en_status": "REJECTED"
    }, {
        "fr": "French",
        "fr_status": "REJECTED"
    }]

}]

I have written a code for it as

$trimArr; //this data array
$finalTempArr = array();
$finalArr = array();


 foreach ($trimArr as $tr) {
       $checkIfExist = $this ->in_array_r($wr['name'], $finalArr);
       if($checkIfExist == false){
           $finalTempArr['name'] =  $tr['name'];
           $finalTempArr['category'] =  $tr['category'];
           $finalTempArr['selectedLanguage'] =  $tr['selectedLanguage'];

       }else {
           array_push($finalTempArr['selectedLanguage'],$tr['selectedLanguage']);
       }

        array_push($finalArr, $finalTempArr);
   }
   echo json_encode($finalArr); 

function in_array_r($needle, $haystack, $strict = false) {
    foreach ($haystack as $item) {
        if (($strict ? $item === $needle : $item == $needle) || (is_array($item) 
        && $this->in_array_r($needle, $item, $strict))) {
            return true;
        }
    }

    return false;
}
Ali
  • 51
  • 2
  • If each row in your incoming array only has one child in the `selectedLanguage` subarray, then you should reduce the complexity of your data structure and just write the language and the language_status. If you might have multiple sets of languages in those subarrays, then everything is cool. – mickmackusa Jun 17 '20 at 08:12

2 Answers2

0

You can just use array_reduce to accomplish it:

$result = array_reduce($array, static function(array $carry, array $item) {
    $key = $item['name'] . $item['category'];

    if (isset($carry[$key])) {
        $carry[$key]['selectedLanguage'] = array_merge($carry[$key]['selectedLanguage'], $item['selectedLanguage']);
    } else {
        $carry[$key] = $item;
    }

    return $carry;
}, []);

if you need fresh keys after reducing, then you can use array_values on the result:

$result = array_values($result);
Mihai Matei
  • 24,166
  • 5
  • 32
  • 50
0

A simple foreach loop will do.

I want to combine on the basis of name

So just use the name as the temporary key while you group and merge the data.

Code: (Demo)

$result = [];
foreach (json_decode($json, true) as $row) {
    if (!isset($result[$row['name']])) {
        $result[$row['name']] = $row;
    } else {
        $result[$row['name']]['selectedLanguage'] = array_merge($result[$row['name']]['selectedLanguage'], $row['selectedLanguage']);
    }
}
var_export(array_values($result));

The more I think about, your subarray structure is probably not fit for purpose. If you are eventually going to be searching for available languages to return the language status, it will be better to set up the array structure to be a "lookup". In other words, each selectedLanguage subarray should be a flat associative array using the language as the key and the language_status as the value. This would look like "en" => "APPROVED".

Alternative, if your scripts are already relying on the en key to find the appropriate values, then keep en as the key and make a flat associative subarray from en. I can't really say with 100% confidence what you should do, but I am reasonably sure that your data structure could be improved. Once you ditch the indexed subarray structure, you then may be able to implement a recursive merge/replace technique.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • I feel pretty confident that this is a duplicate question so if I find a good one, I'll hammer. – mickmackusa Jun 17 '20 at 07:55
  • No upvotes on this page: https://stackoverflow.com/q/27058241/2943403; this one is isn't exactly the same technique: https://stackoverflow.com/q/45264777/2943403 – mickmackusa Jun 17 '20 at 07:56