3

I'm reading an RTF file that gets uploaded by the user, I then exploded this file on each \pard to get each line and then preg_split each line into an array. I then loop over the array looking for a certain value and get the data next to it. All this is working fine but what's the best way to do this multiple times looking for multiple strings? Here is what I have so far:

$data = explode('\pard',$rtf);

foreach ($data as $item) {
    $values = preg_split('/[\t]/', $item);
    if (in_array('shipped yesterday', $values)){
        $key = array_search('shipped yesterday', $values);
        print $values[$key + 1];
    }else{
        print_r($values);
    }
}

The RTF file looks like the following:

booked in yesterday    50    41    78
packaged yesterday     62    45    48
shipped yesterday      46    52    62

So my code above is looking for 'shipped yesterday' then getting the first value next to it, in this case 46.

What's the most efficient way to do it for the rest of the values 'booked in yesterday' and 'packaged yesterday'?

twigg
  • 3,753
  • 13
  • 54
  • 96
  • Look up hash maps, you can probably get a very efficient implementation using them. – Tro Sep 08 '15 at 08:22

3 Answers3

1

I think the fastest way would be a simple regex.

preg_match_all('/((?:booked in|packaged|shipped) yesterday)\s+(\d+)/i',$rtf,$matches);
$values = array();
foreach($matches[1] as $key => $match){
    $values[$match] = $matches[2][$key];
}
print_r($values);

This will parse all matching the given pattern into an array as such

Array ( 
   ['booked in yesterday'] => '50'
   ['packaged yesterday'] => '62'
   ['shipped yesterday'] => '46'
   )

Note if you need the numeric value just parse before passing into the array

$values[$match] = intval($matches[2][$key]);

The output from matches would be like this just to clarify the building of the array:

Array ( 
    [0] => Array ( 
        [0] => 'booked in yesterday 50'
        [1] => 'packaged yesterday 62'
        [2] => 'shipped yesterday 46'
        ) 
    [1] => Array ( 
        [0] => 'booked in yesterday'
        [1] => 'packaged yesterday'
        [2] => 'shipped yesterday'
        ) 
    [2] => Array ( 
        [0] => '50'
        [1] => '62'
        [2] => '46'
        )
    )
0

Your code looks fine to me, you could take an excerpt and use it as a function. HOWEVER, as you asked about efficiency, it's worth noting that isset is faster than in_array

For example...

function checkForValue($searchterm, $values) {
  if (isset($values[$searchterm]))
    return $values[$searchterm];
  }else{
    return "$searchterm not found";
  }
}

$data = explode('\pard',$rtf);

foreach ($data as $item) {
  $values = preg_split('/[\t]/', $item);
  print checkForValue('shipped yesterday', $values);
  print checkForValue('packaged yesterday', $values);
}
Community
  • 1
  • 1
Eddy
  • 534
  • 3
  • 17
0

Maybe you could try running another foreach within an array of the required test strings ?

Have a look at this :-

<?php
$checkString = array("shipped yesterday","booked in yesterday","packaged yesterday");
$data = explode('\pard',$rtf);

foreach ($data as $item) 
{
    $values = preg_split('/[\t]/', $item);
    foreach($checkString as $check)
    {
        if (in_array($check, $values))
        {
            $key = array_search($check, $values);
            print $values[$key + 1];
        }
        else
        {
            print_r($values);
        }
    }

}
?>
Akshay
  • 2,244
  • 3
  • 15
  • 34