Home > Software engineering >  php Optimize multiarray search
php Optimize multiarray search

Time:08-11

I am reading in a file with thousands of lines. I grab the id from each line and check to see if it is in a multiarray, that also has thousands of entries. If it is in the multiarray I need to have the key of the array it is in. I have this all working with the code shown below but it takes a very long time. I'm hoping someone can suggest a way to do it faster?

    $array = [['id' => 'A202977', '550' => 0, '710' => 0],
              ['id' => 'A202978', '550' => 0, '710' => 0],
              ['id' => 'A202979', '550' => 0, '710' => 0]
             ];

    $found = InMultiArray('A202978', $array);
    $key = MultiArraySearch('A202978', $array);
    echo 'Found '.$found .' at '.$key.'<br>';
    //shows Found 1 at 1

    function InMultiArray($needle, $haystack, $strict = false) {
        foreach ($haystack as $item) {
            if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && InMultiArray($needle, $item, $strict))) {
                return true;
            }
        }
        return false;
    }  
       
    function MultiArraySearch($needle, $haystack) {
        foreach ($haystack as $key => $item) {
            if (($needle == $item['id'])) {
                return $key;
           }        
       }
       return FALSE;
    }

CodePudding user response:

You can safely and soundly cache the resulting resources into a JSON file, so next time when you need to load the data, you can just grab the content of the JSON file and pass it as a parameter to json_decode.

So, this is how you could proceed:

  • if the cached file does not exist or it is old, or it is older than the input file
    • proceed in the old and slow way
    • pass the result to json_encode and save it into a cache file
  • else
    • load the cache file's content
    • pass it as a parameter to json_decode and you have your result

Alternatively, you can use a database or even a cache-system, like Redis.

CodePudding user response:

If you really need to find the index of the row by the ID field, you can create an associative array of IDs to array indices.

$array = [['id' => 'A202977', '550' => 0, '710' => 0],
          ['id' => 'A202978', '550' => 0, '710' => 0],
          ['id' => 'A202979', '550' => 0, '710' => 0]
];

// Array to map ID to array index in $dataRaw
$idIndexMap = [];

// Populate structs
foreach ($array as $i=>$currRow)
{
    $idIndexMap[$currRow['id']] = $i;
}

$found = array_key_exists('A202978', $idIndexMap);
$key   = $idIndexMap['A202978'];
echo 'Found ' . $found . ' at ' . $key . '<br>';
//shows Found 1 at 1

However if you just need to find the actual row by the ID, it's probably easier to just create an associative array that maps the ID to the actual row.

<?php
$array = [['id' => 'A202977', '550' => 0, '710' => 0],
          ['id' => 'A202978', '550' => 0, '710' => 0],
          ['id' => 'A202979', '550' => 0, '710' => 0]
];

// Array to map ID to array index in $dataRaw
$map = [];

// Populate structs
foreach ($array as $currRow)
{
    $map[$currRow['id']] = $currRow;
}

$found = array_key_exists('A202978', $map);
$row   = $map['A202978'];
echo 'Found ' . json_encode($row) . '<br>';
  • Related