Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Galera, estou com dor de cabeça tentando achar uma lógica para fazer isso, mas não estou conseguindo.
É o seguinte. Eu quero uma função onde eu informe a chave de um array, e ela adicione um valor como sendo um filho dessa chave.
Explicando melhor. Supondo esse array:
'home' => '/',
'about' => array(
'history' => '/about/history',
'team' => '/about/team',
'offices' => '/about/offices',
),
Eu gostaria de uma função que eu informasse, por exemplo, 'offices' e ela localizasse a chave 'offices', que está dentro de 'about' e adicionasse um filho a ela, ficando assim, o array:
'home' => '/',
'about' => array(
'history' => '/about/history',
'team' => '/about/team',
'offices' => array(
'usa' => '/offices/usa',
),
),
Obs.: É dess jeito mesmo. O array que será adicionado, substituirá o valor original. Lembrando que eu poderia adicionar vários filhos ao mesmo array 'offices.'. Nesse caso o array deveria ficar assim:
'home' => '/',
'about' => array(
'history' => '/about/history',
'team' => '/about/team',
'offices' => array(
'usa' => '/offices/usa',
'uk' => '/offices/uk',
'brazil' => '/offices/brazil',
),
),
Já tentei de tudo, mas os maiores progressos foram com array_walk_recursive(), apensar de nada concreto.
Alguém tem alguma coisa pra me ajudar, alguma lógica, algum material, etc?
Minha dor de cabeça agradece.
Onde estou errando?
<?php
$arr2 = array(
'home' => '/',
'about' => array(
'history' => '/about/history',
'team' => '/about/team',
'offices' => '/about/offices',
),
'services' => array(
'web design' => '/services/webdesign',
'internet marketing' => '/services/markeint',
'hosting' => '/services/hosting',
'domain names' => '/services/domains',
'broadband' => array(
'negas'=>'de pitibiriba'
),
),
'contac us' => array(
'UK' => '/contact/uk ',
'france' => '/contact/france',
'usa' => '/contact/usa',
'australia' => '/contact/aus',
),
'logout' => '/logout'
);
function menudo($array, $chave_procurada, $valor_a_inserir){
foreach($array as $key=>$value):
if(is_string($value)):
if($key==$chave_procurada):
$array2[$key] = $valor_a_inserir;
else:
$array2[$key] = $value;
endif;
elseif(is_array($value)):
$array2[$key] = menudo($value, $chave_procurada, $valor_a_inserir);
endif;
endforeach;
return $array2;
}
print_r(menudo($arr2, 'services', array('new_key'=>'new_value')));
?>>
Onde estou errando?
Aqui vai uma modificação na função que nosso amigo Imaggens passou, agora além buscar recursivamente ela também modifica o conteúdo da sua matriz:
/**
* Percorre uma matriz recursivamente em busca de uma chave específica, se encontrada a função definida por callback será chamada
* @param array $array A matriz que será pesquisada por
* @param mixed $search A chave que será perquisada
* @param string $callback A função que será chamada caso a chave seja encontrada
* @return integer O número de ocorrencias de $search encontradas em $array
*/
function array_key_search_callback( array &$array , $search , $callback ){
$ret = 0;
foreach ( $array as $key => $value ){
if ( $key == $search ){
call_user_func( $callback , &$array[ $key ] );
++$ret;
} else if ( gettype( $value ) == "array" ) $ret += array_key_search_callback( $array[ $key ] , $search , $callback );
}
return( $ret );
}
Esse kara ai em cima irá percorrer sua matriz, se encontrar a chave pesquisada irá chamar uma função que você definir. Depois de varrer toda a matriz ele irá retornar o número de ocorrências da chave na sua matriz, não importando o nível que a chave estiver, para usar:
$dados = array(
'home' => '/',
'about' => array(
'history' => '/about/history',
'team' => '/about/team',
'offices' => array(
'usa' => '/offices/usa',
'uk' => '/offices/uk',
'brazil' => '/offices/brazil',
)
)
);
// A função abaixo é a função que será chamada caso a chave procurada seja encontrada
function teste( $array ){
//Como pode ver, estamos definindo um novo valor para o parâmetro $array, isso é possível porque ele é passado por referência
$array = array( "teste" );
}
// Na linha abaixo temos a chamada da função, o primeiro parâmetro é sua matriz, o segundo a chave que você quer encontrar e o terceiro o nome da função que será chamada
// caso a chave seja encontrada
array_key_search_callback( $dados , "offices" , "teste" );
var_dump( $dados );
A saída será:
array(2) {
["home"]=>
string(1) "/"
["about"]=>
array(3) {
["history"]=>
string(14) "/about/history"
["team"]=>
string(11) "/about/team"
["offices"]=>
array(1) {
[0]=>
string(5) "teste"
}
}
}
Como pode ver, nossa matriz com a chave "offices" foi modificada com o conteúdo que você definiu dentro da função callback. E você também pode usar uma função lambda, se não quiser definir uma função separada:
array_key_search_callback( $dados , "offices" , create_function( '$array' , '
$array = array( "teste" );
' ) );
A saída será exatamente a mesma.
Modifiquei a função do João para não precisar de um callback, criando um tipo de array_deep_push() onde você adiciona um elemento dentro de uma chave específica, mesmo que elas sejam desconhecidas.
function array_deep_push( array &$array, $search, array $var = array() ) {
$ret = 0;
foreach ( $array as $key => $value ) {
if( is_array( $value ) ) {
$ret += array_deep_push( $array[ $key ] , $search , $var );
}
if( $key == $search ) {
$array[ $key ] = array_merge( &$array[ $key ], $var );
++$ret;
}
}
return $ret;
}
E funciona mesmo que você passe outros arrays multimensionais como argumento.
array_deep_push( $a , "offices" , array("brazil" => "/offices/brazil", "germany" => array( "matrix" => "/offices/germany", "branch" => "/offices/germany2" ) ) );
Saída:
Array
(
[home] => /
[about] => Array
(
[history] => /about/history
[team] => /about/team
[offices] => Array
(
[usa] => /offices/usa
[uk] => /offices/uk
[brazil] => /offices/brazil
[germany] => Array
(
[matrix] => /offices/germany
[branch] => /offices/germany2
)
)
)
)Galera, vocês são show!!
Vou testar aqui...
Minha dor de cabeça agradece.. às vezes aparecem umas lógicas que dão nó na cabeça do cara. Mas quando já tá feito parece tão fácil... :)
Valeu
:o
Consegui alguma coisa. Parte da solução apenas.
Encontrei esse snippet:
function array_key_search(array $ar, $key='')
{
Assim, você buscaa matriz de offices e adiciona qualquer outro nela:
Falta agora mesclar com a respectiva chave da matriz original, mas array_merge() não está prestando para isso, pois está adicionando dentro de about, ao invés de detectar a offices e sobrescrevê-la adicionando o elemento.
Outra possível saída seria algo como array_push_recursive() onde você buscaria a matriz offices e dentro dela adicionaria o novo elemento.
Amanhã continuo vendo direito, tenho que buscar "um trenzinho" na escola. :P