Is there a PHP function that simulates a LEFT JOIN?

Asked

Viewed 134 times

4

I’m developing a PHP application that needs to display a graphical indicator. The problem is that the data comes from an external API and depending on the filter applied, the API does not return me points that I need to insert into the chart.

Example:

// Chama a API sem filtros
$dados = $api->get()->limit(6);

var_dump($dados);
// Retorna
  'metaPontual' => 
    array (size=6)
      3 => float 178036332.62
      4 => float 176975684.39
      5 => float 173823421.06
      6 => float 170114093.13
      7 => float 168775993.4
      8 => float 167259382.68

// Aplicando um filtro
$dadosFiltrado = $api->get(['nome' => 'Lucas'])->limit(6);

var_dump($dadosFiltrado);
// O Array Não retorna todos os pontos.
  'metaPontual' => 
    array (size=6)
      1 => float 183635670.39
      4 => float 176975684.39
      5 => float 173823421.06
      6 => float 170114093.13
      8 => float 167259382.68
      9 => float 167259382.68

I need a routine that acts in order to create a "LEFT JOIN" between array 1 and array 2, remembering that arrays are examples, the keys returned by arrays are different, so that:

$arrayFinal = array_left_join(array_keys($dados), $dadosFiltrado);
var_dump($array_final)

  'metaPontual' => 
    array (size=6)
      3 => null
      4 => float 176975684.39
      5 => float 173823421.06
      6 => float 170114093.13
      7 => null
      8 => float 167259382.68
  • 2

    Would be a array_merge that you are seeking?

  • Vc wants a new array with the values they both have in common?

  • @bfavaretto would not be a merge array because I only need the values that both have in common plus the keys of the first array.

  • The keys that only exist in the second are left out so?

  • 1

    Man, there’s no function ready, but play a little with some foreach solves your problem. I eventually do this, but no time to respond now

  • @bfaretto exactly, which only exists in the second array I should disregard.

  • @Emersonrochaluiz I also thought of using a foreach but if possible I would like to avoid its use for reasons of attachment (http://www.phpbench.com/). I’ll run some performance tests with some variations of the code I posted.

Show 2 more comments

3 answers

1

You said you need the values of both arrays PLUS the keys of the 1st, right?

Try it with this:

$array = array_intersect($dados, $dadosFiltrado);
$array_final = (array) ($dados + $array);

var_dump($array_final);
  • is almost that... with array_intersect I’m looking at the values, not the keys.

0


Based on the responses and comments I arrived the following implementations:

function array_left_join($arrayChaves, $arrayValores){
    $arrayIntersect = array_intersect_key($arrayValores, $arrayChaves);
    $chavesLimpas = array_fill_keys(array_keys($arrayChaves), '');

    return array_merge($chavesLimpas, $arrayIntersect);
}

function array_left_join_2($arrayChaves, $arrayValores){
    $chaves = array_keys($arrayChaves);
    $arrayFinal = array();

    foreach ($chaves as $key) {
        $arrayFinal[$key] = !isset($arrayValores[$key]) ? '' : $arrayValores[$key];
    }

    return $arrayFinal;
}

Applying these implementations in a very large array I arrived at the following results.

$arrayTodosOsPontos = array();
$arrayFiltrado = array();

for ($i=10; $i<100000; $i++) {
    $arrayTodosOsPontos[md5("$i")] = 1;
}

for ($i=10; $i<100000; $i++) {
    $arrayFiltrado[md5("$i")] = 4;
}

Debugbar::startMeasure('array_left_join_v1');
$arrayFinal = array_left_join($arrayTodosOsPontos, $arrayFiltrado);
Debugbar::stopMeasure('array_left_join_v1');

Debugbar::startMeasure('array_left_join_v2');
$arrayFinal2 = array_left_join_2($arrayTodosOsPontos, $arrayFiltrado);
Debugbar::stopMeasure('array_left_join_v2');

Teste de Performance

As the second option showed a better performance, I think it better to use it in the project.

0

That solves your problem

array_keys(array_intersect_key($arr1,$arr2));

Returns an array with the keys present in the two arrays

Browser other questions tagged

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