Объединение массивов на основе одних и тех же ключей, но разные значения ключей должны быть добавлены как отдельный массив - PullRequest
1 голос
/ 17 июня 2020

У меня есть данные, которые я вставил ниже. Я хочу объединить на основе имени, т.е. шаблон имени ab c находится на другом языке, я хочу, чтобы он был в информационном имени, категории и всех его языках в одном индексе.

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

Как упоминалось выше Я хочу получить результат как json, вставленный ниже.

[{
    "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"
    }]

}]

Я написал для него код

$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;
}

Ответы [ 2 ]

0 голосов
/ 17 июня 2020

Подойдет простой foreach l oop.

Я хочу объединить на основе имени

Так что просто используйте name как временный при группировании и объединении данных.

Код: ( Демо )

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

Чем больше я думаю, ваша структура подмассива, вероятно, не пригодный для цели. Если вы в конечном итоге собираетесь искать доступные языки, чтобы вернуть статус языка, будет лучше настроить структуру массива как «поиск». Другими словами, каждый подмассив selectedLanguage должен быть плоским ассоциативным массивом с использованием language в качестве ключа и language_status в качестве значения. Это будет выглядеть как "en" => "APPROVED".

Альтернатива: если ваши сценарии уже используют ключ en для поиска подходящих значений, оставьте en в качестве ключа и сделайте плоский ассоциативный подмассив из en. Я не могу сказать со 100% уверенностью, что вам следует делать, но я достаточно уверен, что вашу структуру данных можно улучшить. Как только вы откажетесь от индексированной структуры подмассивов, вы сможете реализовать метод рекурсивного слияния / замены.

0 голосов
/ 17 июня 2020

Вы можете просто использовать array_reduce для выполнения sh 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;
}, []);

если вам нужны fre sh ключи после уменьшения, тогда вы можете использовать array_values в результате:

$result = array_values($result);
...