Remove array positions that have the common name

0

I want to get certain positions of my array that have the names of positions in common, and play for another array .

EX:

array
  'id' => '147' 
  'nome' =>'João' 
  'email' => '[email protected]' 
  'data_nascimento' => '05/01/1987' 
  'numero_1' => '1' 
  'rua_1' => 'rua 1' 
  'numero_2' => '2' 
  'rua_2' => 'rua 2'
  'submit' => 'Salvar' 

Desired result in an array

array
  'numero_1' => '1' 
  'numero_2' => '2'

Or something of the sort

    
asked by anonymous 14.11.2014 / 20:58

4 answers

4

With your current code, for the purpose stated, you can do this:

$arr = array(
  'id'              => '147',
  'nome'            =>'João',
  'email'           => '[email protected]',
  'data_nascimento' => '05/01/1987',
  'numero_1'        => '1',
  'rua_1'           => 'rua 1', 
  'numero_2'        => '2',
  'rua_2'           => 'rua 2',
  'submit'          => 'Salvar' 
);

$newArr = array();

foreach ($arr as $k => $v)                    // por cada entrada na matriz
    if (strpos($k, "numero_") === 0)          // se começar por "numero_"
        $newArr[$k] = $v;                     // envia para a nova matriz

The result will be:

array(2) {
  ["numero_1"]=>
  string(1) "1"
  ["numero_2"]=>
  string(1) "2"
}

See example on Ideone .

    
14.11.2014 / 22:32
5

I thought the intent is to detect any duplicity in the name before the underscore ( underscore ) and not just the "number". And example does not match the description of the question.

So I came up with this code:

$arr = array(
  'id'              => '147',
  'nome'            =>'João',
  'email'           => '[email protected]',
  'data_nascimento' => '05/01/1987',
  'numero_1'        => '1',
  'rua_1'           => 'rua 1', 
  'numero_2'        => '2',
  'rua_2'           => 'rua 2',
  'submit'          => 'Salvar' 
);
$newArr = array();
foreach ($arr as $k => $v) {
    $partes = explode("_", $k);
    if (count($partes) > 1) {
        $repetido = 0;
        foreach ($arr as $k2 => $v2) {
            if (strpos($k2, $partes[0]."_") === 0) {
                $repetido++;
            }
        }
        if ($repetido > 1)
            $newArr[$k] = $v;
    }
}
var_dump($newArr);

See running on ideone . And no Coding Ground . Also I placed GitHub for future reference .

I think you can optimize something but the basis is this.

Result:

array(4) {
  ["numero_1"]=>
  string(1) "1"
  ["rua_1"]=>
  string(5) "rua 1"
  ["numero_2"]=>
  string(1) "2"
  ["rua_2"]=>
  string(5) "rua 2"
}
    
15.11.2014 / 02:06
3

If I understand correctly the purpose is to transfer from the input array all elements that have the same prefix characterized by an expression followed by an underscore .

So, I propose the scheme below:

$filtered = array();

array_walk(

    $arr,

    function( $current, $offset ) use( $arr, &$filtered ) {

         preg_match( '/(\w+_\d+)/', $offset, $matches );

        if( count( $matches ) > 0 && array_key_exists( $matches[ 1 ], $arr ) ) {

            $filtered[ $matches[ 1 ] ] = $current;
        }
    }
);

Using the input array with the same name you have today ( $ arr ) the resulting array $ filtered will have the following values:

array(
  'numero_1' => '1',
  'rua_1' => 'rua 1',
  'numero_2' => '2',
  'rua_2' => 'rua 2'
)

Your second question can be answered simply by computing the difference between the two arrays, original and filtered:

$diff = array_diff_assoc( $arr, $filtered );

The $ diff array has the following values:

array(
  'id' => '147',
  'nome' => 'João',
  'email' => '[email protected]',
  'data_nascimento' => '05/01/1987',
  'submit' => 'Salvar'
)

This approach has the following advantages:

  • Do not depend on a fixed expression, that is, as long as all similarities follow the same format prefix_number , it will work in the entire array.
  • It is fast, because it dispenses calculations, complex conditions and nested loops. So even if large arrays are bad enough for your Application, this procedure is not going to be your bottleneck.
15.11.2014 / 03:00
2

My contribution, mixing some of the answers already given:

$arr = array(
  'id'              => '147',
  'nome'            =>'João',
  'email'           => '[email protected]',
  'data_nascimento' => '05/01/1987',
  'numero_1'        => '1',
  'rua_1'           => 'rua 1', 
  'numero_2'        => '2',
  'rua_2'           => 'rua 2',
  'submit'          => 'Salvar' 
);

$padrao = "/[\w]+\_[\d]+/i";
$chaves = array_keys($arr);

foreach ($arr as $chaveAtual => $valor) {
    preg_match($padrao, $chaveAtual, $encontrados);
    $padraoEncontrado = count($encontrados);
    $padraoSeRepete = (int) preg_grep($padrao,$chaves);
    if ((!$padraoEncontrado) || (!$padraoSeRepete)) {
        unset($arr[$chaveAtual]);
    }
}

var_dump($arr);

/*
Resultado:
array(4) {  
  ["numero_1"]=>
  string(1) "1"
  ["rua_1"]=>
  string(5) "rua 1"
  ["numero_2"]=>
  string(1) "2"
  ["rua_2"]=>
  string(5) "rua 2"
}
*/
    
15.11.2014 / 16:43