How to merge identical array values, and place the different ones inside a sub-array

Asked

Viewed 188 times

0

I have the following problem.

I have an array returned from the database which is as follows:

array(4) {
[0]=>
  array(4) {
    ["groupoURL"]=> string(7) "express"
    ["grupoNome"]=> string(13) "Express"
    ["subgrupoURL"]=> string(4) "aves"
    ["subgrupoNome"]=> string(4) "Aves"
  }
[1]=>
  array(4) {
    ["groupoURL"]=> string(7) "express"
    ["grupoNome"]=> string(13) "Express"
    ["subgrupoURL"]=> string(4) "peixes"
    ["subgrupoNome"]=> string(4) "Peixes"
  }
[2]=>
  array(4) {
    ["groupoURL"]=> string(7) "executivo"
    ["grupoNome"]=> string(13) "Executivo"
    ["subgrupoURL"]=> string(4) "aves"
    ["subgrupoNome"]=> string(4) "Aves"
  }
[3]=>
  array(4) {
    ["groupoURL"]=> string(7) "executivo"
    ["grupoNome"]=> string(13) "Executivo"
    ["subgrupoURL"]=> string(4) "carnes"
    ["subgrupoNome"]=> string(4) "Carnes"
  }
}

I am trying to merge the values that are identical (In this case, it will always be the keys "groupURL" and "groupName", and the remaining "subgroupURL" and "subgroupName" should become an array and their values be joined.

My end result would need to stay this way:

array(2) {
[0]=>
  array(3) {
    ["groupoURL"]=> string(7) "express"
    ["grupoNome"]=> string(13) "Express"
    ["subgrupos"]=> array(
        array(
            ["subgrupoURL"]=> "aves",
            ["subgrupoNome"]=> "Aves"
        ),
        array(
            ["subgrupoURL"]=> "peixes",
            ["subgrupoNome"]=> "Peixes"
        ),
    )
  }
[1]=>
  array(3) {
    ["groupoURL"]=> string(7) "executivo"
    ["grupoNome"]=> string(13) "Executivo"
    ["subgrupos"]=> array(
        array(
            ["subgrupoURL"]=> "aves",
            ["subgrupoNome"]=> "Aves"
        ),
        array(
            ["subgrupoURL"]=> "carnes",
            ["subgrupoNome"]=> "Carnes"
        ),
    )
  }
}

I don’t have a solution yet, but I’m trying to create something, but this wouldn’t be the ideal way:

    $test = ...Recebe os resultados da consulta
    $newArray = [];
    foreach($test as $array) {
        switch ($array["groupoURL"]) {
            case "express":
                 $newArray["express"]["grupoNome"] = $array["grupoNome"];
                 $newArray["express"]["grupoURL"] = $array["groupoURL"];
                 $newArray["express"]["subgrupos"][] = ["subgrupoNome" => $array["subgrupoNome"], "subgrupoURL" => $array["subgrupoURL"]];
                 break;
            case "executivo":
                 $newArray["executivo"]["grupoNome"] = $array["grupoNome"];
                 $newArray["executivo"]["grupoURL"] = $array["groupoURL"];
                 $newArray["executivo"]["subgrupos"][] = ["subgrupoNome" => $array["subgrupoNome"], "subgrupoURL" => $array["subgrupoURL"]];
                 break;
            ...
            default: 
                break;
        }
    }

The above solution works, but I am checking the "group" of each item. It may happen that the name of this group is changed, or a new group is inserted.

Would anyone have any suggestions? Thank you for your attention.

  • Update your question with what you tried, to correct if necessary.

  • It would not be better if you adjust your query to already return the information in this format?

  • André, I thought what you said, to return the data I need to consult in 3 tables, I got an alternative result using the "GROUP_CONCAT". In this case it will return me a record for each group and two more columns, one with the subgroups separated by comma and the other with the url of the subgroups. [catN | Catu | [subn, sub2n] | [Subu, subU2]] From this I would have to do a treatment to get the desired result. Would you have any other suggestions? Because I think I’ll end up with this second way, although I’m curious with the answer of the original question

  • Need exactly the structure you posted? Another way is to use the groupURL fields as the key of the array.

  • Something like this: http://sandbox.onlinephpfunctions.com/code/00d1354a27b821b245c8285f6aaf503accf8a98f

1 answer

1


In hand:

<?php

$resultSet = [
    [
        'grupoURL'     => 'express',
        'grupoNome'    => 'Express',
        'subgrupoURL'  => 'aves',
        'subgrupoNome' => 'Aves'
    ],
    [
         'grupoURL'     => 'express',
         'grupoNome'    => 'Express',
         'subgrupoURL'  => 'peixes',
         'subgrupoNome' => 'Peixes'
    ],
    [
         'grupoURL'     => 'executivo',
         'grupoNome'    => 'Executivo',
         'subgrupoURL'  => 'aves',
         'subgrupoNome' => 'Aves'
    ],
    [
         'grupoURL'     => 'executivo',
         'grupoNome'    => 'Executivo',
         'subgrupoURL'  => 'carnes',
         'subgrupoNome' => 'Carnes'
    ]
];

$arrayFinal = [];

for ($i=0; $i<count($resultSet); $i++) {
    $inserido = false;
    for ($j=0; $j<count($arrayFinal); $j++) {
        if ($arrayFinal[$j]['grupoURL'] == $resultSet[$i]['grupoURL'] && $arrayFinal[$j]['grupoNome'] == $resultSet[$i]['grupoNome']) {
            $inserido = true;
            $arrayFinal[$j]['subgrupos'][] = [
                'subgrupoURL'  => $resultSet[$i]['subgrupoURL'],
                'subgrupoNome' => $resultSet[$i]['subgrupoNome']
            ];
        }
    }
    if (!$inserido) {
        $arrayFinal[] = [
            'grupoURL'  => $resultSet[$i]['grupoURL'],
            'grupoNome' => $resultSet[$i]['grupoNome'],
            'subgrupos' => [
                [
                    'subgrupoURL'  => $resultSet[$i]['subgrupoURL'],
                    'subgrupoNome' => $resultSet[$i]['subgrupoNome']
                ]
            ]
        ];
    }
}

What is done: the resultset is traversed and, at each iteration, the keys are checked grupoNome and grupoURL are already present in the final array. If so, we place the other elements as sub-elements. Otherwise, we create a new index in the final array and fill it with the data from resultset.

  • Thanks a lot, it worked fine.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.