Is there a function in PHP that simulates a LEFT JOIN?

4

I'm developing an application in PHP 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 points 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 to create a "LEFT JOIN" between array 1 and array 2, remembering that the arrays are examples, the keys returned by the 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
    
asked by anonymous 21.02.2014 / 19:09

3 answers

0

Based on the responses and comments I got 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 to a very large array I have achieved 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');

Since the second option showed better performance, I think it's better to use it in the project.

    
24.02.2014 / 21:12
1

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

Try this:

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

var_dump($array_final);
    
21.02.2014 / 19:25
0

This solves your problem

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

Returns an array with the keys present in the two arrays

    
21.02.2014 / 19:28