Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP : Search all record from array with specific value

Tags:

php

I have 2 arrays.

    $a = ( 
           array( 'number' => $value, 'name' => $name ),
           array( 'number' => $value, 'name' => $name ),
           array( 'number' => $value, 'name' => $name ), 
         );
    $b = ( 
           array( 'number' => $value, 'address' => $address ),
           array( 'number' => $value, 'address' => $address ),
           array( 'number' => $value, 'address' => $address ),
           ...
         );

Now, lets say for a particular record in $a having 'number' = 10. Is there a way in PHP that I can extract all the addresses from $b having 'number' = 10. I am using foreach at the moment but it takes too long as I have more than 5000 records in $a and more than 20000 records in $b.

    $result = array();  

    foreach ($a as $tempA) {
      $result[]['number'] => $tempA['number'];
      $result[]['name'] => $tempA['name'];
      $address = array();

      foreach($b as $tempB) {
        if($tempB['number'] !== $tempA['number'])
          continue;
        $address[] = $tempB;
      }
      $result[]['addresses'] = $address;
    }

So the result will be like this:

   $result = (
    ('number' => 10, 'name' => 'xyz', 'addresses' => array(<contains all addresses with number 10>) )
   )
like image 234
Tejas Gosai Avatar asked Mar 04 '26 04:03

Tejas Gosai


2 Answers

Here is a solution that only involves iterating each array once which should significantly reduce the processing time needed:

$a = array(
    array('number' => 1, 'name' => 'Bob'),
    array('number' => 2, 'name' => 'Sue'),
    array('number' => 3, 'name' => 'Jim'),
    array('number' => 4, 'name' => 'Cal'),
);

$b = array(
    array('number' => 1, 'address' => 'Address 1A'),
    array('number' => 1, 'address' => 'Address 1B'),
    array('number' => 1, 'address' => 'Address 1C'),
    array('number' => 2, 'address' => 'Address 2A'),
    array('number' => 2, 'address' => 'Address 2B'),
    array('number' => 4, 'address' => 'Address 4A'),
    array('number' => 4, 'address' => 'Address 4B'),
    array('number' => 4, 'address' => 'Address 4C'),
    array('number' => 4, 'address' => 'Address 4D'),
    array('number' => 4, 'address' => 'Address 4E'),
);

// Create array $c to index address records by key
$c = array();
foreach ($b as $item) {
    $key = $item['number'];
        if (!array_key_exists($key, $c)) {
            $c[$key] = array();
        }
        $c[$key][] = $item['address'];
}

// Now loop through $a creating the address on array $a by accessing $c by key
foreach ($a as $index => $item) {
    $key = $a[$index]['number'];
    $a[$index]['addresses'] = $c[$key];
}

// The result now lives in array $a
var_dump($a);
like image 187
Luke Cordingley Avatar answered Mar 05 '26 18:03

Luke Cordingley


You may use array_* functions:

function findAddressesByNumber($number, $names, $addresses){
    $found_names = array_values(
        array_filter($names, function ($v) use ($number) {
            return $v['number'] == $number;
        })
    );
    if (!count($found_names)) return false;
    $found_addrs = array_map(
        function ($v) { return $v['address']; },
        array_filter($addresses, function ($v) use ($number) {
            return $v['number'] == $number;
        })
    );
    return array(
        'number' => $number,
        'name' => $found_names[0]['name'],
        'addresses' => $found_addrs
    );
}
like image 23
hindmost Avatar answered Mar 05 '26 16:03

hindmost